// 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.

@TestOn('vm')
@Timeout(Duration(minutes: 2))
library;

import 'package:dwds/src/debugging/dart_scope.dart';
import 'package:dwds/src/services/chrome_proxy_service.dart';
import 'package:test/test.dart';
import 'package:test_common/logging.dart';
import 'package:test_common/test_sdk_configuration.dart';
import 'package:vm_service/vm_service.dart';

import 'fixtures/context.dart';
import 'fixtures/project.dart';
import 'fixtures/utilities.dart';

void main() {
  // set to true for debug logging.
  final debug = false;

  final provider = TestSdkConfigurationProvider(verbose: debug);
  tearDownAll(provider.dispose);

  final context = TestContext(TestProject.testScopes, provider);

  setUpAll(() async {
    setCurrentLogWriter(debug: debug);
    await context.setUp(testSettings: TestSettings(verboseCompiler: debug));
  });

  tearDownAll(() async {
    await context.tearDown();
  });

  group('temporary variable regular expression', () {
    setUpAll(() => setCurrentLogWriter(debug: debug));
    test('matches correctly for pre-patterns temporary variables', () {
      expect(previousDdcTemporaryVariableRegExp.hasMatch(r't4$'), isTrue);
      expect(previousDdcTemporaryVariableRegExp.hasMatch(r't4$0'), isTrue);
      expect(previousDdcTemporaryVariableRegExp.hasMatch(r't4$10'), isTrue);
      expect(previousDdcTemporaryVariableRegExp.hasMatch(r't4$0'), isTrue);
      expect(previousDdcTemporaryVariableRegExp.hasMatch(r't1'), isTrue);
      expect(previousDdcTemporaryVariableRegExp.hasMatch(r't10'), isTrue);
      expect(previousDdcTemporaryVariableRegExp.hasMatch(r'__t$TL'), isTrue);
      expect(
        previousDdcTemporaryVariableRegExp.hasMatch(r'__t$StringN'),
        isTrue,
      );
      expect(
        previousDdcTemporaryVariableRegExp.hasMatch(
          r'__t$IdentityMapOfString$T',
        ),
        isTrue,
      );

      expect(previousDdcTemporaryVariableRegExp.hasMatch(r't'), isFalse);
      expect(previousDdcTemporaryVariableRegExp.hasMatch(r't10foo'), isFalse);
      expect(previousDdcTemporaryVariableRegExp.hasMatch(r't$10foo'), isFalse);
    });

    test('matches correctly for post-patterns temporary variables', () {
      expect(ddcTemporaryVariableRegExp.hasMatch(r't$364$'), isTrue);
      expect(ddcTemporaryVariableRegExp.hasMatch(r't$364$0'), isTrue);
      expect(ddcTemporaryVariableRegExp.hasMatch(r't$364$10'), isTrue);
      expect(ddcTemporaryVariableRegExp.hasMatch(r't$364$0'), isTrue);
      expect(ddcTemporaryVariableRegExp.hasMatch(r't$361'), isTrue);
      expect(ddcTemporaryVariableRegExp.hasMatch(r't$36$350$350'), isTrue);
      expect(
        ddcTemporaryVariableRegExp.hasMatch(r't$36$350$354$35isSet'),
        isTrue,
      );
      expect(
        ddcTemporaryVariableRegExp.hasMatch(r't$36$35variable$35isSet'),
        isTrue,
      );
      expect(
        ddcTemporaryVariableRegExp.hasMatch(r'synthetic$35variable'),
        isTrue,
      );
      expect(ddcTemporaryTypeVariableRegExp.hasMatch(r'__t$TL'), isTrue);
      expect(ddcTemporaryTypeVariableRegExp.hasMatch(r'__t$StringN'), isTrue);
      expect(
        ddcTemporaryTypeVariableRegExp.hasMatch(r'__t$IdentityMapOfString$T'),
        isTrue,
      );

      expect(ddcTemporaryVariableRegExp.hasMatch(r't'), isFalse);
      expect(ddcTemporaryVariableRegExp.hasMatch(r'this'), isFalse);
      expect(ddcTemporaryVariableRegExp.hasMatch(r'\$this'), isFalse);
      expect(ddcTemporaryVariableRegExp.hasMatch(r't10'), isFalse);
      expect(ddcTemporaryVariableRegExp.hasMatch(r't10foo'), isFalse);
      expect(ddcTemporaryVariableRegExp.hasMatch(r'ten'), isFalse);
      expect(ddcTemporaryVariableRegExp.hasMatch(r'my$3635variable'), isFalse);
    });
  });

  group('variable scope', () {
    late ChromeProxyService service;
    VM vm;
    String? isolateId;
    late Stream<Event> stream;
    ScriptList scripts;
    late ScriptRef mainScript;
    Stack stack;

    // TODO: Be able to set breakpoints before start/reload so we can exercise
    // things that aren't in recurring loops.

    /// Support function for pausing and returning the stack at a line.
    Future<Stack> breakAt(String breakpointId, ScriptRef scriptRef) async {
      final lineNumber = await context.findBreakpointLine(
        breakpointId,
        isolateId!,
        scriptRef,
      );

      final bp = await service.addBreakpoint(
        isolateId!,
        scriptRef.id!,
        lineNumber,
      );
      // Wait for breakpoint to trigger.
      await stream.firstWhere(
        (event) => event.kind == EventKind.kPauseBreakpoint,
      );
      // Remove breakpoint so it doesn't impact other tests.
      await service.removeBreakpoint(isolateId!, bp.id!);
      final stack = await service.getStack(isolateId!);
      return stack;
    }

    Future<Instance> getInstance(InstanceRef ref) async {
      final result = await service.getObject(isolateId!, ref.id!);
      expect(result, isA<Instance>());
      return result as Instance;
    }

    void expectDartObject(String variableName, Instance instance) {
      expect(
        instance,
        isA<Instance>().having(
          (instance) => instance.classRef!.name,
          '$variableName: classRef.name',
          isNot(
            isIn(['NativeJavaScriptObject', 'JavaScriptObject', 'NativeError']),
          ),
        ),
      );
    }

    Future<void> expectDartVariables(
      Map<String?, InstanceRef?> variables,
    ) async {
      for (final name in variables.keys) {
        final instance = await getInstance(variables[name]!);
        expectDartObject(name!, instance);
      }
    }

    Map<String?, InstanceRef?> getFrameVariables(Frame frame) {
      return <String?, InstanceRef?>{
        for (final variable in frame.vars!)
          variable.name: variable.value as InstanceRef?,
      };
    }

    setUpAll(() => setCurrentLogWriter(debug: debug));

    setUp(() async {
      service = context.service;
      vm = await service.getVM();
      isolateId = vm.isolates!.first.id;
      scripts = await service.getScripts(isolateId!);
      await service.streamListen('Debug');
      stream = service.onEvent('Debug');
      mainScript = scripts.scripts!.firstWhere(
        (each) => each.uri!.contains('main.dart'),
      );
    });

    tearDown(() async {
      await service.resume(isolateId!);
    });

    test('variables in static function', () async {
      stack = await breakAt('staticFunction', mainScript);
      final variables = getFrameVariables(stack.frames!.first);
      await expectDartVariables(variables);

      final variableNames = variables.keys.toList()..sort();
      expect(variableNames, containsAll(['formal']));
    });

    test('variables in static async function', () async {
      stack = await breakAt('staticAsyncFunction', mainScript);
      final variables = getFrameVariables(stack.frames!.first);
      await expectDartVariables(variables);

      final variableNames = variables.keys.toList()..sort();
      final variableValues =
          variableNames.map((name) => variables[name]?.valueAsString).toList();
      expect(variableNames, containsAll(['myLocal', 'value']));
      expect(variableValues, containsAll(['a local value', 'arg1']));
    });

    test('variables in static async loop function', () async {
      stack = await breakAt('staticAsyncLoopFunction', mainScript);
      final variables = getFrameVariables(stack.frames!.first);
      await expectDartVariables(variables);

      final variableNames = variables.keys.toList()..sort();
      final variableValues =
          variableNames.map((name) => variables[name]?.valueAsString).toList();
      expect(variableNames, containsAll(['i', 'myLocal', 'value']));
      // Ensure the loop variable, i, is captued correctly. The value from the
      // first iteration should be captured by the saved closure.
      expect(variableValues, containsAll(['1', 'my local value', 'arg2']));
    });

    test('variables in function', () async {
      stack = await breakAt('nestedFunction', mainScript);
      final variables = getFrameVariables(stack.frames!.first);
      await expectDartVariables(variables);

      final variableNames = variables.keys.toList()..sort();
      expect(
        variableNames,
        containsAll([
          'aClass',
          'another',
          'intLocalInMain',
          'local',
          'localThatsNull',
          'nestedFunction',
          'parameter',
          'testClass',
        ]),
      );
    });

    test('variables in closure nested in method', () async {
      stack = await breakAt('nestedClosure', mainScript);
      final variables = getFrameVariables(stack.frames!.first);
      await expectDartVariables(variables);

      final variableNames = variables.keys.toList()..sort();
      expect(variableNames, [
        'closureLocalInsideMethod',
        'local',
        'parameter',
        'this',
      ]);
    });

    test('variables in method', () async {
      stack = await breakAt('printMethod', mainScript);
      final variables = getFrameVariables(stack.frames!.first);
      await expectDartVariables(variables);

      final variableNames = variables.keys.toList()..sort();
      expect(variableNames, ['this']);
    });

    test('variables in extension method', () async {
      stack = await breakAt('extension', mainScript);
      final variables = getFrameVariables(stack.frames!.first);
      await expectDartVariables(variables);

      final variableNames = variables.keys.toList()..sort();
      // Note: '$this' should change to 'this', and 'return' should
      // disappear after debug symbols are available.
      // https://github.com/dart-lang/webdev/issues/1371
      expect(variableNames, ['\$this', 'ret', 'return']);
    });

    test('evaluateJsOnCallFrame', () async {
      stack = await breakAt('nestedFunction', mainScript);
      final debugger = await service.debuggerFuture;
      final parameter = await debugger.evaluateJsOnCallFrameIndex(
        0,
        'parameter',
      );
      expect(parameter.value, matches(RegExp(r'\d+ world')));
      final ticks = await debugger.evaluateJsOnCallFrameIndex(1, 'ticks');
      // We don't know how many ticks there were before we stopped, but it should
      // be a positive number.
      expect(ticks.value, isPositive);
    });
  });
}
