// Copyright (c) 2020, 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))
import 'dart:async';

import 'package:dwds/src/services/expression_evaluator.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 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

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

void testAll({
  required TestSdkConfigurationProvider provider,
  CompilationMode compilationMode = CompilationMode.buildDaemon,
  IndexBaseMode indexBaseMode = IndexBaseMode.noBase,
  NullSafety nullSafety = NullSafety.sound,
  bool useDebuggerModuleNames = false,
  bool debug = false,
}) {
  if (compilationMode == CompilationMode.buildDaemon &&
      indexBaseMode == IndexBaseMode.base) {
    throw StateError(
      'build daemon scenario does not support non-empty base in index file',
    );
  }

  final testProject = TestProject.test(nullSafety: nullSafety);
  final testPackageProject =
      TestProject.testPackage(nullSafety: nullSafety, baseMode: indexBaseMode);

  final context = TestContext(testPackageProject, provider);

  Future<void> onBp(
    Stream<Event> stream,
    String isolate,
    ScriptRef script,
    String breakPointId,
    Future<void> Function(Event event) body,
  ) async {
    Breakpoint? bp;
    try {
      final line =
          await context.findBreakpointLine(breakPointId, isolate, script);
      bp = await context.service
          .addBreakpointWithScriptUri(isolate, script.uri!, line);
      final event = await stream.firstWhere(
        (event) => event.kind == EventKind.kPauseBreakpoint,
      );
      await body(event);
    } finally {
      // Remove breakpoint so it doesn't impact other tests or retries.
      if (bp != null) {
        await context.service.removeBreakpoint(isolate, bp.id!);
      }
    }
  }

  group(
    'Shared context with evaluation |',
    () {
      setUpAll(() async {
        setCurrentLogWriter(debug: debug);
        await context.setUp(
          testSettings: TestSettings(
            compilationMode: compilationMode,
            moduleFormat: provider.ddcModuleFormat,
            enableExpressionEvaluation: true,
            useDebuggerModuleNames: useDebuggerModuleNames,
            verboseCompiler: debug,
          ),
        );
      });

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

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

      group('evaluateInFrame |', () {
        VM vm;
        late Isolate isolate;
        late String isolateId;
        ScriptList scripts;
        late ScriptRef mainScript;
        late ScriptRef libraryScript;
        late ScriptRef testLibraryScript;
        late ScriptRef testLibraryPartScript;
        late Stream<Event> stream;
        late StreamController<String> output;

        setUp(() async {
          output = StreamController<String>.broadcast();
          output.stream.listen(debug ? print : printOnFailure);

          configureLogWriter(
            customLogWriter: (level, message, {error, loggerName, stackTrace}) {
              final e = error == null ? '' : ': $error';
              final s = stackTrace == null ? '' : ':\n$stackTrace';
              if (!output.isClosed) {
                output.add('[$level] $loggerName: $message$e$s');
              }
            },
          );

          vm = await context.service.getVM();
          isolate = await context.service.getIsolate(vm.isolates!.first.id!);
          isolateId = isolate.id!;
          scripts = await context.service.getScripts(isolateId);

          await context.service.streamListen('Debug');
          stream = context.service.onEvent('Debug');

          final testPackage = testPackageProject.packageName;
          final test = testProject.packageName;
          mainScript = scripts.scripts!
              .firstWhere((each) => each.uri!.contains('main.dart'));
          testLibraryScript = scripts.scripts!.firstWhere(
            (each) =>
                each.uri!.contains('package:$testPackage/test_library.dart'),
          );
          testLibraryPartScript = scripts.scripts!.firstWhere(
            (each) =>
                each.uri!.contains('package:$testPackage/src/test_part.dart'),
          );
          libraryScript = scripts.scripts!.firstWhere(
            (each) => each.uri!.contains('package:$test/library.dart'),
          );
        });

        tearDown(() async {
          await output.close();
          try {
            await context.service.resume(isolateId);
          } catch (_) {}
        });

        onBreakPoint(script, bpId, body) => onBp(
              stream,
              isolateId,
              script,
              bpId,
              body,
            );

        evaluateInFrame(frame, expr, {scope}) async =>
            await context.service.evaluateInFrame(
              isolateId,
              frame,
              expr,
              scope: scope,
            );

        getInstanceRef(frame, expr, {scope}) async {
          final result = await evaluateInFrame(
            frame,
            expr,
            scope: scope,
          );
          expect(result, isA<InstanceRef>());
          return result as InstanceRef;
        }

        getInstance(InstanceRef ref) async =>
            await context.service.getObject(isolateId, ref.id!) as Instance;

        test('with scope', () async {
          await onBreakPoint(mainScript, 'printFrame1', (event) async {
            final frame = event.topFrame!.index!;

            final scope = {
              'x1': (await getInstanceRef(frame, '"cat"')).id!,
              'x2': (await getInstanceRef(frame, '2')).id!,
              'x3': (await getInstanceRef(frame, 'MainClass(1,0)')).id!,
            };

            final result = await getInstanceRef(
              frame,
              '"\$x1\$x2 (\$x3) \$testLibraryValue (\$local1)"',
              scope: scope,
            );

            expect(result, matchInstanceRef('cat2 (1, 0) 3 (1)'));
          });
        });

        test('with large scope', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            const N = 20;
            final frame = event.topFrame!.index!;

            final scope = {
              for (var i = 0; i < N; i++)
                'x$i': (await getInstanceRef(frame, '$i')).id!,
            };
            final expression = [
              for (var i = 0; i < N; i++) '\$x$i',
            ].join(' ');
            final expected = [
              for (var i = 0; i < N; i++) '$i',
            ].join(' ');

            final result = await evaluateInFrame(
              frame,
              '"$expression"',
              scope: scope,
            );
            expect(result, matchInstanceRef(expected));
          });
        });

        test('with large code scope', () async {
          await onBreakPoint(mainScript, 'printLargeScope', (event) async {
            const xN = 2;
            const tN = 20;
            final frame = event.topFrame!.index!;

            final scope = {
              for (var i = 0; i < xN; i++)
                'x$i': (await getInstanceRef(frame, '$i')).id!,
            };
            final expression = [
              for (var i = 0; i < xN; i++) '\$x$i',
              for (var i = 0; i < tN; i++) '\$t$i',
            ].join(' ');
            final expected = [
              for (var i = 0; i < xN; i++) '$i',
              for (var i = 0; i < tN; i++) '$i',
            ].join(' ');

            final result = await evaluateInFrame(
              frame,
              '"$expression"',
              scope: scope,
            );
            expect(result, matchInstanceRef(expected));
          });
        });

        test('with scope in caller frame', () async {
          await onBreakPoint(mainScript, 'printFrame1', (event) async {
            final frame = event.topFrame!.index! + 1;

            final scope = {
              'x1': (await getInstanceRef(frame, '"cat"')).id!,
              'x2': (await getInstanceRef(frame, '2')).id!,
              'x3': (await getInstanceRef(frame, 'MainClass(1,0)')).id!,
            };

            final result = await getInstanceRef(
              frame,
              '"\$x1\$x2 (\$x3) \$testLibraryValue (\$local2)"',
              scope: scope,
            );

            expect(result, matchInstanceRef('cat2 (1, 0) 3 (2)'));
          });
        });

        test('with scope and this', () async {
          await onBreakPoint(mainScript, 'toStringMainClass', (event) async {
            final frame = event.topFrame!.index!;

            final scope = {
              'x1': (await getInstanceRef(frame, '"cat"')).id!,
            };

            final result = await getInstanceRef(
              frame,
              '"\$x1 \${this._field} \${this.field}"',
              scope: scope,
            );

            expect(result, matchInstanceRef('cat 1 2'));
          });
        });

        test(
          'extension method scope variables can be evaluated',
          () async {
            await onBreakPoint(mainScript, 'extension', (event) async {
              final stack = await context.service.getStack(isolateId);
              final scope = _getFrameVariables(stack.frames!.first);
              for (var p in scope.entries) {
                final name = p.key;
                final value = p.value as InstanceRef;
                final result =
                    await getInstanceRef(event.topFrame!.index!, name!);

                expect(result, matchInstanceRef(value.valueAsString));
              }
            });
          },
          skip: 'https://github.com/dart-lang/webdev/issues/1371',
        );

        test('uses correct null safety mode', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final isNullSafetyEnabledExpression =
                '() { const sound = !(<Null>[] is List<int>); return sound; } ()';
            final result = await getInstanceRef(
              event.topFrame!.index!,
              isNullSafetyEnabledExpression,
            );
            final expectedResult = '${nullSafety == NullSafety.sound}';
            expect(result, matchInstanceRef(expectedResult));
          });
        });

        test('does not crash if class metadata cannot be found', () async {
          await onBreakPoint(mainScript, 'printStream', (event) async {
            final instanceRef =
                await getInstanceRef(event.topFrame!.index!, 'stream');
            final instance = await getInstance(instanceRef);

            expect(instance, matchInstance('_AsBroadcastStream<int>'));
          });
        });

        test('local', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'local',
            );

            expect(result, matchInstanceRef('42'));
          });
        });

        test('Type does not show native JavaScript object fields', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final instanceRef =
                await getInstanceRef(event.topFrame!.index!, 'Type');

            // Type
            final instance = await getInstance(instanceRef);
            for (var field in instance.fields!) {
              final name = field.decl!.name;
              final fieldInstance =
                  await getInstance(field.value as InstanceRef);

              expect(
                fieldInstance,
                isA<Instance>().having(
                  (i) => i.classRef!.name,
                  'Type.$name: classRef.name',
                  isNot(
                    isIn([
                      'NativeJavaScriptObject',
                      'JavaScriptObject',
                    ]),
                  ),
                ),
              );
            }
          });
        });

        test('field', () async {
          await onBreakPoint(mainScript, 'printFieldFromLibraryClass',
              (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'instance.field',
            );

            expect(result, matchInstanceRef('1'));
          });
        });

        test('private field from another library', () async {
          await onBreakPoint(mainScript, 'printFieldFromLibraryClass',
              (event) async {
            final result = await evaluateInFrame(
              event.topFrame!.index!,
              'instance._field',
            );

            expect(
              result,
              matchErrorRef(contains("The getter '_field' isn't defined")),
            );
          });
        });

        test('private field from current library', () async {
          await onBreakPoint(mainScript, 'printFieldMain', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'instance._field',
            );

            expect(result, matchInstanceRef('1'));
          });
        });

        test('access instance fields after evaluation', () async {
          await onBreakPoint(mainScript, 'printFieldFromLibraryClass',
              (event) async {
            final instanceRef = await getInstanceRef(
              event.topFrame!.index!,
              'instance',
            );

            final instance = await getInstance(instanceRef);
            final field = instance.fields!.firstWhere(
              (BoundField element) => element.decl!.name == 'field',
            );

            expect(field.value, matchInstanceRef('1'));
          });
        });

        test('global', () async {
          await onBreakPoint(mainScript, 'printGlobal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'testLibraryValue',
            );

            expect(result, matchInstanceRef('3'));
          });
        });

        test('call core function', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'print(local)',
            );

            expect(result, matchInstanceRef('null'));
          });
        });

        test('call library function with const param', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'testLibraryFunction(42)',
            );

            expect(result, matchInstanceRef('42'));
          });
        });

        test('call library function with local param', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'testLibraryFunction(local)',
            );

            expect(result, matchInstanceRef('42'));
          });
        });

        test('call library part function with const param', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'testLibraryPartFunction(42)',
            );

            expect(result, matchInstanceRef('42'));
          });
        });

        test('call library part function with local param', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'testLibraryPartFunction(local)',
            );

            expect(result, matchInstanceRef('42'));
          });
        });

        test('loop variable', () async {
          await onBreakPoint(mainScript, 'printLoopVariable', (event) async {
            final result = await getInstanceRef(event.topFrame!.index!, 'item');

            expect(result, matchInstanceRef('1'));
          });
        });

        test('evaluate expression in _test_package/test_library', () async {
          await onBreakPoint(testLibraryScript, 'testLibraryFunction',
              (event) async {
            final result =
                await getInstanceRef(event.topFrame!.index!, 'formal');

            expect(result, matchInstanceRef('23'));
          });
        });

        test('evaluate expression in a class constructor in a library',
            () async {
          await onBreakPoint(testLibraryScript, 'testLibraryClassConstructor',
              (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'this.field',
            );

            expect(result, matchInstanceRef('1'));
          });
        });

        test('evaluate expression in a class constructor in a library part',
            () async {
          await onBreakPoint(
              testLibraryPartScript, 'testLibraryPartClassConstructor',
              (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'this.field',
            );

            expect(result, matchInstanceRef('1'));
          });
        });

        test('evaluate expression in caller frame', () async {
          await onBreakPoint(testLibraryScript, 'testLibraryFunction',
              (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index! + 1,
              'local',
            );

            expect(result, matchInstanceRef('23'));
          });
        });

        test('evaluate expression in a library', () async {
          await onBreakPoint(libraryScript, 'Concatenate', (event) async {
            final result = await getInstanceRef(event.topFrame!.index!, 'a');

            expect(result, matchInstanceRef('Hello'));
          });
        });

        test('compilation error', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final error = await evaluateInFrame(event.topFrame!.index!, 'typo');

            expect(
              error,
              matchErrorRef(contains(EvaluationErrorKind.compilation)),
            );
          });
        });

        test('async frame error', () async {
          final maxAttempts = 100;

          Response? error;
          String? breakpointId;
          try {
            // Pause in client.js directly to force pausing in async code.
            breakpointId = await _setBreakpointInInjectedClient(
              context.tabConnection.debugger,
            );

            var attempt = 0;
            do {
              try {
                await context.service.resume(isolateId);
              } catch (_) {}

              final event = stream.firstWhere(
                (event) => event.kind == EventKind.kPauseInterrupted,
              );
              final frame = (await event).topFrame;
              if (frame != null) {
                error = await context.service.evaluateInFrame(
                  isolateId,
                  frame.index!,
                  'true',
                );
              }
              expect(
                attempt,
                lessThan(maxAttempts),
                reason:
                    'Failed to receive and async frame error in $attempt attempts',
              );
              await (Future.delayed(const Duration(milliseconds: 10)));
              attempt++;
            } while (error is! ErrorRef);
          } finally {
            if (breakpointId != null) {
              await context.tabConnection.debugger
                  .removeBreakpoint(breakpointId);
            }
          }

          // Verify we receive an error when evaluating
          // on async frame.
          expect(
            error,
            matchErrorRef(contains(EvaluationErrorKind.asyncFrame)),
          );

          // Verify we don't emit errors or warnings
          // on async frame evaluations.
          output.stream.listen((event) {
            expect(event, isNot(contains('[WARNING]')));
            expect(event, isNot(contains('[SEVERE]')));
          });
        });

        test(
          'module load error',
          () async {
            await onBreakPoint(mainScript, 'printLocal', (event) async {
              final error = await evaluateInFrame(
                event.topFrame!.index!,
                'd.deferredPrintLocal()',
              );

              expect(
                error,
                matchErrorRef(contains(EvaluationErrorKind.loadModule)),
              );
            });
          },
          skip: 'https://github.com/dart-lang/sdk/issues/48587',
        );

        test('cannot evaluate in unsupported isolate', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            await expectLater(
              context.service
                  .evaluateInFrame('bad', event.topFrame!.index!, 'local'),
              throwsSentinelException,
            );
          });
        });
      });

      group('evaluate |', () {
        VM vm;
        late Isolate isolate;
        late String isolateId;

        setUp(() async {
          setCurrentLogWriter(debug: debug);
          final service = context.service;
          vm = await service.getVM();
          isolate = await service.getIsolate(vm.isolates!.first.id!);
          isolateId = isolate.id!;

          await service.streamListen('Debug');
        });

        tearDown(() async {});

        evaluate(
          libraryId,
          expr, {
          scope,
        }) async =>
            await context.service.evaluate(
              isolateId,
              libraryId,
              expr,
              scope: scope,
            );

        getInstanceRef(
          libraryId,
          expr, {
          scope,
        }) async {
          final result = await evaluate(
            libraryId,
            expr,
            scope: scope,
          );
          expect(result, isA<InstanceRef>());
          return result as InstanceRef;
        }

        String getRootLibraryId() {
          expect(isolate.rootLib, isNotNull);
          expect(isolate.rootLib!.id, isNotNull);
          return isolate.rootLib!.id!;
        }

        test('with scope', () async {
          final libraryId = getRootLibraryId();

          final scope = {
            'x1': (await getInstanceRef(libraryId, '"cat"')).id!,
            'x2': (await getInstanceRef(libraryId, '2')).id!,
            'x3': (await getInstanceRef(libraryId, 'MainClass(1,0)')).id!,
          };

          final result = await getInstanceRef(
            libraryId,
            '"\$x1\$x2 (\$x3) \$testLibraryValue"',
            scope: scope,
          );

          expect(result, matchInstanceRef('cat2 (1, 0) 3'));
        });

        test('with large scope', () async {
          final libraryId = getRootLibraryId();
          const N = 2;

          final scope = {
            for (var i = 0; i < N; i++)
              'x$i': (await getInstanceRef(libraryId, '$i')).id!,
          };
          final expression = [
            for (var i = 0; i < N; i++) '\$x$i',
          ].join(' ');
          final expected = [
            for (var i = 0; i < N; i++) '$i',
          ].join(' ');

          final result = await getInstanceRef(
            libraryId,
            '"$expression"',
            scope: scope,
          );
          expect(result, matchInstanceRef(expected));
        });

        test('in parallel (in a batch)', () async {
          final libraryId = getRootLibraryId();

          final evaluation1 =
              getInstanceRef(libraryId, 'MainClass(1,0).toString()');
          final evaluation2 =
              getInstanceRef(libraryId, 'MainClass(1,1).toString()');

          final results = await Future.wait([evaluation1, evaluation2]);
          expect(results[0], matchInstanceRef('1, 0'));
          expect(results[1], matchInstanceRef('1, 1'));
        });

        test('in parallel (in a batch) handles errors', () async {
          final libraryId = getRootLibraryId();
          final missingLibId = '';

          final evaluation1 =
              evaluate(missingLibId, 'MainClass(1,0).toString()');
          final evaluation2 = evaluate(libraryId, 'MainClass(1,1).toString()');

          final results = await Future.wait([evaluation1, evaluation2]);

          expect(
            results[0],
            matchErrorRef(contains('No batch result object ID')),
          );
          expect(
            results[1],
            matchErrorRef(contains('No batch result object ID')),
          );
        });

        test('with scope override', () async {
          final libraryId = getRootLibraryId();

          final param = await getInstanceRef(libraryId, 'MainClass(1,0)');
          final result = await getInstanceRef(
            libraryId,
            't.toString()',
            scope: {'t': param.id!},
          );

          expect(result, matchInstanceRef('1, 0'));
        });

        test('uses symbol from the same library', () async {
          final libraryId = getRootLibraryId();

          final result =
              await getInstanceRef(libraryId, 'MainClass(1,0).toString()');

          expect(result, matchInstanceRef('1, 0'));
        });

        test('uses symbol from another library', () async {
          final libraryId = getRootLibraryId();
          final result = await getInstanceRef(
            libraryId,
            'TestLibraryClass(0,1).toString()',
          );

          expect(result, matchInstanceRef('field: 0, _field: 1'));
        });

        test('closure call', () async {
          final libraryId = getRootLibraryId();
          final result = await getInstanceRef(libraryId, '(() => 42)()');

          expect(result, matchInstanceRef('42'));
        });
      });
    },
    timeout: const Timeout.factor(2),
  );

  group('shared context with no evaluation |', () {
    setUpAll(() async {
      setCurrentLogWriter(debug: debug);
      await context.setUp(
        testSettings: TestSettings(
          compilationMode: compilationMode,
          moduleFormat: provider.ddcModuleFormat,
          enableExpressionEvaluation: false,
          verboseCompiler: debug,
        ),
      );
    });

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

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

    group('evaluateInFrame |', () {
      VM vm;
      late Isolate isolate;
      late String isolateId;
      ScriptList scripts;
      late ScriptRef mainScript;
      late Stream<Event> stream;

      setUp(() async {
        final service = context.service;
        vm = await service.getVM();
        isolate = await service.getIsolate(vm.isolates!.first.id!);
        isolateId = isolate.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 context.service.resume(isolateId);
      });

      test('cannot evaluate expression', () async {
        await onBp(stream, isolateId, mainScript, 'printLocal', (event) async {
          await expectLater(
            context.service
                .evaluateInFrame(isolateId, event.topFrame!.index!, 'local'),
            throwsRPCError,
          );
        });
      });
    });
  });
}

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

Future<String> _setBreakpointInInjectedClient(WipDebugger debugger) async {
  final client = 'dwds/src/injected/client.js';
  final clientScript =
      debugger.scripts.values.firstWhere((e) => e.url.contains(client));
  final clientSource = await debugger.getScriptSource(clientScript.scriptId);

  final line = clientSource.split('\n').indexWhere(
        (element) => element.contains('convertDartClosureToJS'),
      );

  final result = await debugger.sendCommand(
    'Debugger.setBreakpointByUrl',
    params: {
      'urlRegex': '.*$client',
      'lineNumber': line + 4,
      'columnNumber': 0,
    },
  );
  return result.json['result']['breakpointId'];
}

Matcher matchInstanceRef(dynamic value) => isA<InstanceRef>().having(
      (instance) => instance.valueAsString,
      'valueAsString',
      value,
    );

Matcher matchInstance(dynamic className) => isA<Instance>().having(
      (instance) => instance.classRef!.name,
      'class name',
      className,
    );

Matcher matchErrorRef(dynamic message) => isA<ErrorRef>().having(
      (instance) => instance.message,
      'message',
      message,
    );
