// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Timeout(Duration(minutes: 2))
library;

import 'dart:async';
import 'dart:convert';

import 'package:dwds/data/devtools_request.dart';
import 'package:dwds/data/extension_request.dart';
import 'package:dwds/src/servers/extension_debugger.dart';
import 'package:test/test.dart';

import 'fixtures/debugger_data.dart';
import 'fixtures/fakes.dart';

late FakeSseConnection connection;
late ExtensionDebugger extensionDebugger;

void main() async {
  setUp(() async {
    connection = FakeSseConnection();
    extensionDebugger = ExtensionDebugger(connection);
  });

  tearDown(() {
    connection.controllerIncoming.close();
    connection.controllerOutgoing.close();
  });

  group('can receive', () {
    test('an ExtensionResponse', () async {
      final extensionResponse = ExtensionResponse(
        id: 0,
        success: true,
        result: jsonEncode({
          'result': {'value': 3.14},
        }),
      );
      final resultCompleter = Completer();
      unawaited(
        extensionDebugger
            .sendCommand('Runtime.evaluate', params: {'expression': '\$pi'})
            .then(resultCompleter.complete),
      );
      connection.controllerIncoming.sink.add(jsonEncode(extensionResponse));
      final response = await resultCompleter.future;
      expect(response.result['result']['value'], 3.14);
    });

    test('an ExtensionEvent', () async {
      final extensionEvent = ExtensionEvent(
        method: jsonEncode('Debugger.paused'),
        params: jsonEncode(frames1Json[0]),
      );
      connection.controllerIncoming.sink.add(jsonEncode(extensionEvent));
      final wipEvent = await extensionDebugger.onNotification.first;
      expect(wipEvent.method, 'Debugger.paused');
      expect(wipEvent.params, frames1Json[0]);
    });

    test('a BatchedEvents', () async {
      final event1 = ExtensionEvent(
        method: jsonEncode('Debugger.scriptParsed'),
        params: jsonEncode(scriptParsedParams),
      );
      final event2 = ExtensionEvent(
        method: jsonEncode('Debugger.scriptParsed'),
        params: jsonEncode(scriptParsedParams),
      );
      final batch = BatchedEvents(events: [event1, event2]);
      connection.controllerIncoming.sink.add(jsonEncode(batch));
      final wipEvent = await extensionDebugger.onNotification.first;
      expect(wipEvent.method, 'Debugger.scriptParsed');
      expect(wipEvent.params, scriptParsedParams);
    });

    test('a DevToolsRequest', () async {
      final devToolsRequest = DevToolsRequest(
        appId: '3.14',
        instanceId: '6.28',
        tabUrl: 'pi/calculus',
      );
      connection.controllerIncoming.sink.add(jsonEncode(devToolsRequest));
      final request = await extensionDebugger.devToolsRequestStream.first;
      expect(request.tabUrl, 'pi/calculus');
      expect(request.appId, '3.14');
      expect(request.instanceId, '6.28');
    });
  });

  group('can send', () {
    test('a request with empty params', () async {
      final extensionRequest = ExtensionRequest(
        id: 0,
        command: 'Debugger.pause',
        commandParams: jsonEncode({}),
      );
      unawaited(extensionDebugger.pause());
      final decoded = jsonDecode(
        await connection.controllerOutgoing.stream.first,
      );
      final request = ExtensionRequest.fromJson(decoded);
      expect(request, extensionRequest);
    });

    test('a request with some params', () async {
      final params = {
        'location': {'scriptId': '555', 'lineNumber': 28},
      };
      final extensionRequest = ExtensionRequest(
        id: 0,
        command: 'Debugger.setBreakpoint',
        commandParams: jsonEncode(params),
      );
      unawaited(
        extensionDebugger.sendCommand('Debugger.setBreakpoint', params: params),
      );
      final decoded = jsonDecode(
        await connection.controllerOutgoing.stream.first,
      );
      final request = ExtensionRequest.fromJson(decoded);
      expect(request, extensionRequest);
    });
  });
  group('when closed', () {
    test('DebugExtension.detached event closes the connection', () async {
      final extensionEvent = ExtensionEvent(
        method: jsonEncode('DebugExtension.detached'),
        params: jsonEncode({}),
      );

      connection.controllerIncoming.sink.add(jsonEncode(extensionEvent));
      // Expect the connection to receive a close event:
      expect(await extensionDebugger.onClose.first, isNotNull);
    });

    test(
      'gracefully handles trying to send events after the connection is closed',
      () async {
        // Close the connection:
        final extensionEvent = ExtensionEvent(
          method: jsonEncode('DebugExtension.detached'),
          params: jsonEncode({}),
        );
        connection.controllerIncoming.sink.add(jsonEncode(extensionEvent));
        // Wait for it to be closed:
        await extensionDebugger.onClose.first;
        // Try to send an event:
        Future<void> callToSendCommand() => extensionDebugger.sendCommand(
          'Debugger.setBreakpoint',
          params: {
            'location': {'scriptId': '555', 'lineNumber': 28},
          },
        );
        // Should not throw any errors:
        expect(callToSendCommand, returnsNormally);
      },
    );
  });
}
