// 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:path/path.dart' as path;
import 'package:test/test.dart';

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

main() {
  group('debug mode', () {
    late DapTestSession dap;
    setUp(() async {
      dap = await DapTestSession.setUp();
    });
    tearDown(() => dap.tearDown());

    test('can attach to a simple script using vmServiceUri', () async {
      final testFile = dap.createTestFile(simpleArgPrintingProgram);

      final args = ['one', 'two'];
      final proc = await startDartProcessPaused(
        testFile.path,
        args,
        cwd: dap.testAppDir.path,
      );
      final vmServiceUri = await waitForStdoutVmServiceBanner(proc);

      final outputEvents = await dap.client.collectOutput(
        launch: () => dap.client.attach(
          vmServiceUri: vmServiceUri.toString(),
          autoResume: true,
          cwd: dap.testAppDir.path,
        ),
      );

      // Expect a "console" output event that prints the URI of the VM Service
      // the debugger connects to.
      final vmConnection = outputEvents.first;
      expect(vmConnection.output,
          startsWith('Connecting to VM Service at ws://127.0.0.1:'));
      expect(vmConnection.category, equals('console'));

      // Expect the normal applications output.
      final output = outputEvents
          .skip(1)
          .map((e) => e.output)
          // The stdout also contains the Observatory+DevTools banners.
          .where(
            (line) =>
                !line.startsWith('Observatory listening on') &&
                !line.startsWith(
                    'The Dart DevTools debugger and profiler is available at'),
          )
          .join();
      expectLines(output, [
        'Hello!',
        'World!',
        'args: [one, two]',
        '',
        'Exited.',
      ]);
    });

    test('can attach to a simple script using vmServiceInfoFile', () async {
      final testFile = dap.createTestFile(simpleArgPrintingProgram);

      // Spawn the program using --write-service-info which we'll pass the path
      // of directly to the DAP to read.
      final vmServiceInfoFilePath = path.join(
        dap.testAppDir.path,
        'vmServiceInfo.json',
      );
      await startDartProcessPaused(
        testFile.path,
        ['one', 'two'],
        cwd: dap.testAppDir.path,
        vmArgs: ['--write-service-info=${Uri.file(vmServiceInfoFilePath)}'],
      );
      final outputEvents = await dap.client.collectOutput(
        launch: () => dap.client.attach(
          vmServiceInfoFile: vmServiceInfoFilePath,
          autoResume: true,
          cwd: dap.testAppDir.path,
        ),
      );

      // Expect a "console" output event that prints the URI of the VM Service
      // the debugger connects to.
      final vmConnection = outputEvents.first;
      expect(
        vmConnection.output,
        startsWith('Connecting to VM Service at ws://127.0.0.1:'),
      );
      expect(vmConnection.category, equals('console'));

      // Expect the normal applications output.
      final output = outputEvents
          .skip(1)
          .map((e) => e.output)
          // The stdout also contains the Observatory+DevTools banners.
          .where(
            (line) =>
                !line.startsWith('Observatory listening on') &&
                !line.startsWith(
                    'The Dart DevTools debugger and profiler is available at'),
          )
          .join();
      expectLines(output, [
        'Hello!',
        'World!',
        'args: [one, two]',
        '',
        'Exited.',
      ]);
    });

    test('removes breakpoints/pause and resumes on detach', () async {
      final testFile = dap.createTestFile(simpleBreakpointAndThrowProgram);

      final proc = await startDartProcessPaused(
        testFile.path,
        [],
        cwd: dap.testAppDir.path,
      );
      final vmServiceUri = await waitForStdoutVmServiceBanner(proc);

      // Attach to the paused script without resuming and wait for the startup
      // pause event.
      await Future.wait([
        dap.client.expectStop('entry'),
        dap.client.start(
          launch: () => dap.client.attach(
            vmServiceUri: vmServiceUri.toString(),
            autoResume: false,
            cwd: dap.testAppDir.path,
          ),
        ),
      ]);

      // Set a breakpoint that we expect not to be hit, as detach should disable
      // it and resume.
      final breakpointLine = lineWith(testFile, breakpointMarker);
      await dap.client.setBreakpoint(testFile, breakpointLine);

      // Detach using terminateRequest. Despite the name, terminateRequest is
      // the request for a graceful detach (and disconnectRequest is the
      // forceful shutdown).
      await dap.client.terminate();

      // Expect the process terminates (and hasn't got stuck on the breakpoint
      // or exception).
      await proc.exitCode;
    });

    // These tests can be slow due to starting up the external server process.
  }, timeout: Timeout.none);
}
