// Copyright (c) 2021, 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.

import 'package:dds/src/dap/adapters/dart.dart';
import 'package:test/test.dart';

import 'test_client.dart';
import 'test_scripts.dart';
import 'test_support.dart';

main() {
  late DapTestSession dap;
  setUp(() async {
    dap = await DapTestSession.setUp();
  });
  tearDown(() => dap.tearDown());

  group('debug mode evaluation', () {
    test('evaluates expressions with simple results', () async {
      final client = dap.client;
      final testFile = await dap.createTestFile('''
void main(List<String> args) {
  var a = 1;
  var b = 2;
  var c = 'test';
  print('Hello!'); $breakpointMarker
}''');
      final breakpointLine = lineWith(testFile, breakpointMarker);

      final stop = await client.hitBreakpoint(testFile, breakpointLine);
      final topFrameId = await client.getTopFrameId(stop.threadId!);
      await client.expectEvalResult(topFrameId, 'a', '1');
      await client.expectEvalResult(topFrameId, 'a * b', '2');
      await client.expectEvalResult(topFrameId, 'c', '"test"');
    });

    test('evaluates expressions with complex results', () async {
      final client = dap.client;
      final testFile = await dap.createTestFile(simpleBreakpointProgram);
      final breakpointLine = lineWith(testFile, breakpointMarker);

      final stop = await client.hitBreakpoint(testFile, breakpointLine);
      final topFrameId = await client.getTopFrameId(stop.threadId!);
      final result = await client.expectEvalResult(
        topFrameId,
        'DateTime(2000, 1, 1)',
        'DateTime',
      );

      // Check we got a variablesReference that maps on to the fields.
      expect(result.variablesReference, isPositive);
      await client.expectVariables(
        result.variablesReference,
        '''
            isUtc: false, eval: DateTime(2000, 1, 1).isUtc
        ''',
      );
    });

    test('evaluates expressions ending with semicolons', () async {
      final client = dap.client;
      final testFile = await dap.createTestFile('''
void main(List<String> args) {
  var a = 1;
  var b = 2;
  print('Hello!'); $breakpointMarker
}''');
      final breakpointLine = lineWith(testFile, breakpointMarker);

      final stop = await client.hitBreakpoint(testFile, breakpointLine);
      final topFrameId = await client.getTopFrameId(stop.threadId!);
      await client.expectEvalResult(topFrameId, 'a + b;', '3');
    });

    test(
        'evaluates complex expressions expressions with evaluateToStringInDebugViews=true',
        () async {
      final client = dap.client;
      final testFile = await dap.createTestFile(simpleBreakpointProgram);
      final breakpointLine = lineWith(testFile, breakpointMarker);

      final stop = await client.hitBreakpoint(
        testFile,
        breakpointLine,
        launch: () =>
            client.launch(testFile.path, evaluateToStringInDebugViews: true),
      );

      final topFrameId = await client.getTopFrameId(stop.threadId!);
      await client.expectEvalResult(
        topFrameId,
        'DateTime(2000, 1, 1)',
        'DateTime (2000-01-01 00:00:00.000)',
      );
    });

    test(
        'evaluates $threadExceptionExpression to the threads exception (simple type)',
        () async {
      final client = dap.client;
      final testFile = await dap.createTestFile(r'''
void main(List<String> args) {
  throw 'my error';
}''');

      final stop = await client.hitException(testFile);
      final topFrameId = await client.getTopFrameId(stop.threadId!);
      final result = await client.expectEvalResult(
        topFrameId,
        threadExceptionExpression,
        '"my error"',
      );
      expect(result.variablesReference, equals(0));
    });

    test(
        'evaluates $threadExceptionExpression to the threads exception (complex type)',
        () async {
      final client = dap.client;
      final testFile = await dap.createTestFile(r'''
void main(List<String> args) {
  throw Exception('my error');
}''');

      final stop = await client.hitException(testFile);
      final topFrameId = await client.getTopFrameId(stop.threadId!);
      final result = await client.expectEvalResult(
        topFrameId,
        threadExceptionExpression,
        '_Exception',
      );
      expect(result.variablesReference, isPositive);
    });

    test(
        'evaluates $threadExceptionExpression.x.y to x.y on the threads exception',
        () async {
      final client = dap.client;
      final testFile = await dap.createTestFile(r'''
void main(List<String> args) {
  throw Exception('12345');
}
    ''');

      final stop = await client.hitException(testFile);
      final topFrameId = await client.getTopFrameId(stop.threadId!);
      await client.expectEvalResult(
        topFrameId,
        '$threadExceptionExpression.message.length',
        '5',
      );
    });

    test('can evaluate expressions in non-top frames', () async {
      final client = dap.client;
      final testFile = await dap.createTestFile('''
void main(List<String> args) {
  var a = 999;
  foo();
}

void foo() {
  var a = 111; $breakpointMarker
}''');
      final breakpointLine = lineWith(testFile, breakpointMarker);

      final stop = await client.hitBreakpoint(testFile, breakpointLine);
      final stack = await client.getValidStack(stop.threadId!,
          startFrame: 0, numFrames: 2);
      final secondFrameId = stack.stackFrames[1].id;

      await client.expectEvalResult(secondFrameId, 'a', '999');
    });

    test('returns the full message for evaluation errors', () async {
      final client = dap.client;
      final testFile = await dap.createTestFile(simpleBreakpointProgram);
      final breakpointLine = lineWith(testFile, breakpointMarker);

      final stop = await client.hitBreakpoint(testFile, breakpointLine);
      final topFrameId = await client.getTopFrameId(stop.threadId!);
      expectResponseError(
        client.evaluate(
          '1 + "a"',
          frameId: topFrameId,
        ),
        allOf([
          contains('evaluateInFrame: (113) Expression compilation error'),
          contains("'String' can't be assigned to a variable of type 'num'."),
          contains(
            '1 + "a"\n'
            '    ^',
          )
        ]),
      );
    });

    test('returns short errors for evaluation in "watch" context', () async {
      final client = dap.client;
      final testFile = await dap.createTestFile(simpleBreakpointProgram);
      final breakpointLine = lineWith(testFile, breakpointMarker);

      final stop = await client.hitBreakpoint(testFile, breakpointLine);
      final topFrameId = await client.getTopFrameId(stop.threadId!);
      expectResponseError(
        client.evaluate(
          '1 + "a"',
          frameId: topFrameId,
          context: 'watch',
        ),
        equals(
          "A value of type 'String' can't be assigned "
          "to a variable of type 'num'.",
        ),
      );
    });
    // These tests can be slow due to starting up the external server process.
  }, timeout: Timeout.none);
}
