// 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))
import 'dart:async';
import 'dart:convert';

import 'package:built_collection/built_collection.dart';
import 'package:dwds/data/devtools_request.dart';
import 'package:dwds/data/extension_request.dart';
import 'package:dwds/data/serializers.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(
        (b) => b
          ..result = jsonEncode({
            'result': {'value': 3.14},
          })
          ..id = 0
          ..success = true,
      );
      final resultCompleter = Completer();
      unawaited(
        extensionDebugger.sendCommand(
          'Runtime.evaluate',
          params: {'expression': '\$pi'},
        ).then(resultCompleter.complete),
      );
      connection.controllerIncoming.sink
          .add(jsonEncode(serializers.serialize(extensionResponse)));
      final response = await resultCompleter.future;
      expect(response.result['result']['value'], 3.14);
    });

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

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

    test('a DevToolsRequest', () async {
      final devToolsRequest = DevToolsRequest(
        (b) => b
          ..tabUrl = 'pi/calculus'
          ..appId = '3.14'
          ..instanceId = '6.28',
      );
      connection.controllerIncoming.sink
          .add(jsonEncode(serializers.serialize(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(
        (b) => b
          ..id = 0
          ..command = 'Debugger.pause'
          ..commandParams = jsonEncode({}),
      );
      unawaited(extensionDebugger.pause());
      final request = serializers.deserialize(
        jsonDecode(await connection.controllerOutgoing.stream.first),
      );
      expect(request, extensionRequest);
    });

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

      connection.controllerIncoming.sink
          .add(jsonEncode(serializers.serialize(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(
        (b) => b
          ..method = jsonEncode('DebugExtension.detached')
          ..params = jsonEncode({}),
      );
      connection.controllerIncoming.sink
          .add(jsonEncode(serializers.serialize(extensionEvent)));
      // Wait for it to be closed:
      await extensionDebugger.onClose.first;
      // Try to send an event:
      callToSendCommand() => extensionDebugger.sendCommand(
            'Debugger.setBreakpoint',
            params: {
              'location': {'scriptId': '555', 'lineNumber': 28},
            },
          );
      // Should not throw any errors:
      expect(callToSendCommand, returnsNormally);
    });
  });
}
