// Copyright (c) 2023, 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:dwds/data/devtools_request.dart';
import 'package:dwds/data/extension_request.dart';
import 'package:dwds/data/serializers.dart';
import 'package:dwds/src/debugging/execution_context.dart';
import 'package:dwds/src/servers/extension_debugger.dart';
import 'package:test/test.dart';
import 'package:test_common/logging.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

import 'fixtures/fakes.dart';

void main() async {
  final bool debug = false;

  group('ExecutionContext', () {
    setUpAll(() {
      setCurrentLogWriter(debug: debug);
    });

    TestDebuggerConnection? debugger;
    TestDebuggerConnection getDebugger() => debugger!;

    setUp(() async {
      setCurrentLogWriter(debug: debug);
      debugger = TestDebuggerConnection();
    });

    tearDown(() async {
      await debugger?.close();
    });

    test('is created on devtools request', () async {
      final debugger = getDebugger();
      await debugger.createDebuggerExecutionContext(TestContextId.dartDefault);

      // Expect the context ID to be set.
      expect(await debugger.defaultContextId(), TestContextId.dartDefault);
    });

    test('clears context ID', () async {
      final debugger = getDebugger();
      await debugger.createDebuggerExecutionContext(TestContextId.dartDefault);

      debugger.sendContextsClearedEvent();

      // Expect non-dart context.
      expect(await debugger.defaultContextId(), TestContextId.none);
    });

    test('finds dart context ID', () async {
      final debugger = getDebugger();
      await debugger.createDebuggerExecutionContext(TestContextId.none);

      debugger.sendContextCreatedEvent(TestContextId.dartNormal);

      // Expect dart context.
      expect(await debugger.dartContextId(), TestContextId.dartNormal);
    });

    test('does not find dart context ID if not available', () async {
      final debugger = getDebugger();
      await debugger.createDebuggerExecutionContext(TestContextId.none);

      // No context IDs received yet.
      expect(await debugger.defaultContextId(), TestContextId.none);

      debugger.sendContextCreatedEvent(TestContextId.dartLate);

      // Expect no dart context.
      // This mocks injected client still loading.
      expect(await debugger.noContextId(), TestContextId.none);

      // Expect dart context.
      // This mocks injected client loading later for previously
      // received context ID.
      expect(await debugger.dartContextId(), TestContextId.dartLate);
    });

    test('works with stale contexts', () async {
      final debugger = getDebugger();
      await debugger.createDebuggerExecutionContext(TestContextId.none);

      debugger.sendContextCreatedEvent(TestContextId.stale);

      // Expect no dart context.
      expect(await debugger.noContextId(), TestContextId.none);

      debugger.sendContextsClearedEvent();
      debugger.sendContextCreatedEvent(TestContextId.dartNormal);

      // Expect dart context.
      expect(await debugger.dartContextId(), TestContextId.dartNormal);
    });
  });
}

enum TestContextId {
  none,
  dartDefault,
  dartNormal,
  dartLate,
  nonDart,
  stale;

  factory TestContextId.from(int? value) {
    return switch (value) {
      null => none,
      0 => dartDefault,
      1 => dartNormal,
      2 => dartLate,
      3 => nonDart,
      4 => stale,
      _ => throw StateError('$value is not a TestContextId'),
    };
  }

  int? get id {
    return switch (this) {
      none => null,
      dartDefault => 0,
      dartNormal => 1,
      dartLate => 2,
      nonDart => 3,
      stale => 4,
    };
  }
}

class TestExtensionDebugger extends ExtensionDebugger {
  TestExtensionDebugger(FakeSseConnection super.sseConnection);

  @override
  Future<WipResponse> sendCommand(
    String command, {
    Map<String, dynamic>? params,
  }) {
    final id = params?['contextId'];
    final response = super.sendCommand(command, params: params);

    /// Mock stale contexts that cause the evaluation to throw.
    if (command == 'Runtime.evaluate' &&
        TestContextId.from(id) == TestContextId.stale) {
      throw Exception('Stale execution context');
    }
    return response;
  }
}

class TestDebuggerConnection {
  late final TestExtensionDebugger extensionDebugger;
  late final FakeSseConnection connection;

  int _evaluateRequestId = 0;

  TestDebuggerConnection() {
    connection = FakeSseConnection();
    extensionDebugger = TestExtensionDebugger(connection);
  }

  /// Create a new execution context in the debugger.
  Future<void> createDebuggerExecutionContext(TestContextId contextId) {
    _sendDevToolsRequest(contextId: contextId.id);
    return _executionContext();
  }

  /// Flush the streams and close debugger connection.
  Future<void> close() async {
    unawaited(connection.controllerOutgoing.stream.any((e) => false));
    unawaited(extensionDebugger.devToolsRequestStream.any((e) => false));

    await connection.controllerIncoming.sink.close();
    await connection.controllerOutgoing.sink.close();

    await extensionDebugger.close();
  }

  /// Return the initial context ID from the DevToolsRequest.
  Future<TestContextId> defaultContextId() async {
    // Give the previous events time to propagate.
    await Future.delayed(Duration(milliseconds: 100));
    return TestContextId.from(await extensionDebugger.executionContext!.id);
  }

  /// Mock receiving dart context ID in the execution context.
  ///
  /// Note: dart context is detected by evaluation of
  /// `window.$dartAppInstanceId` in that context returning
  /// a non-null value.
  Future<TestContextId> dartContextId() async {
    // Try getting execution id.
    final executionContextId = extensionDebugger.executionContext!.id;

    // Give it time to send the evaluate request.
    await Future.delayed(Duration(milliseconds: 100));

    // Respond to the evaluate request.
    _sendEvaluationResponse({
      'result': {'value': 'dart'},
    });

    return TestContextId.from(await executionContextId);
  }

  /// Mock receiving non-dart context ID in the execution context.
  ///
  /// Note: dart context is detected by evaluation of
  /// `window.$dartAppInstanceId` in that context returning
  /// a null value.
  Future<TestContextId> noContextId() async {
    // Try getting execution id.
    final executionContextId = extensionDebugger.executionContext!.id;

    // Give it time to send the evaluate request.
    await Future.delayed(Duration(milliseconds: 100));

    // Respond to the evaluate request.
    _sendEvaluationResponse({
      'result': {'value': null},
    });

    return TestContextId.from(await executionContextId);
  }

  /// Send `Runtime.executionContextsCleared` event to the execution
  /// context in the extension debugger.
  void sendContextsClearedEvent() {
    final extensionEvent = ExtensionEvent(
      (b) => b
        ..method = jsonEncode('Runtime.executionContextsCleared')
        ..params = jsonEncode({}),
    );
    connection.controllerIncoming.sink
        .add(jsonEncode(serializers.serialize(extensionEvent)));
  }

  /// Send `Runtime.executionContextCreated` event to the execution
  /// context in the extension debugger.
  void sendContextCreatedEvent(TestContextId contextId) {
    final extensionEvent = ExtensionEvent(
      (b) => b
        ..method = jsonEncode('Runtime.executionContextCreated')
        ..params = jsonEncode({
          'context': {'id': '${contextId.id}'},
        }),
    );
    connection.controllerIncoming.sink
        .add(jsonEncode(serializers.serialize(extensionEvent)));
  }

  void _sendEvaluationResponse(Map<String, dynamic> response) {
    // Respond to the evaluate request.
    final extensionResponse = ExtensionResponse(
      (b) => b
        ..result = jsonEncode(response)
        ..id = _evaluateRequestId++
        ..success = true,
    );
    connection.controllerIncoming.sink
        .add(jsonEncode(serializers.serialize(extensionResponse)));
  }

  void _sendDevToolsRequest({int? contextId}) {
    final devToolsRequest = DevToolsRequest(
      (b) => b
        ..contextId = contextId
        ..appId = 'app'
        ..instanceId = '0',
    );
    connection.controllerIncoming.sink
        .add(jsonEncode(serializers.serialize(devToolsRequest)));
  }

  Future<void> _executionContext() async {
    final executionContext = await _waitForExecutionContext().timeout(
      const Duration(milliseconds: 100),
      onTimeout: () {
        expect(fail, 'Timeout getting execution context');
        return null;
      },
    );
    expect(executionContext, isNotNull);
  }

  Future<ExecutionContext?> _waitForExecutionContext() async {
    while (extensionDebugger.executionContext == null) {
      await Future.delayed(Duration(milliseconds: 20));
    }
    return extensionDebugger.executionContext;
  }
}
