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

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:path/path.dart' as path;
import 'package:test/test.dart';

import '../utils.dart';

const String soundNullSafetyMessage = 'Info: Compiling with sound null safety';
const devToolsMessagePrefix =
    'The Dart DevTools debugger and profiler is available at: http://127.0.0.1:';
const observatoryMessagePrefix = 'Observatory listening on http://127.0.0.1:';

void main() {
  group('run', run, timeout: longTimeout);
}

void run() {
  late TestProject p;

  tearDown(() async => await p.dispose());

  test('--help', () async {
    p = project();
    var result = await p.run(['run', '--help']);

    expect(result.stdout, contains('Run a Dart program.'));
    expect(result.stdout, contains('Debugging options:'));
    expect(
      result.stdout,
      contains(
        'Usage: dart run [arguments] [<dart-file|package-target> [args]]',
      ),
    );
    expect(result.stderr, isEmpty);
    expect(result.exitCode, 0);
  });

  test('--help --verbose', () async {
    p = project();
    var result = await p.run(['run', '--help', '--verbose']);

    expect(result.stdout, contains('Run a Dart program.'));
    expect(result.stdout, contains('Debugging options:'));
    expect(
      result.stdout,
      contains(
        'Usage: dart [vm-options] run [arguments] [<dart-file|package-target> [args]]',
      ),
    );
    expect(result.stderr, isEmpty);
    expect(result.exitCode, 0);
  });

  test("'Hello World'", () async {
    p = project(mainSrc: "void main() { print('Hello World'); }");
    ProcessResult result = await p.run(['run', p.relativeFilePath]);

    expect(result.stdout, contains('Hello World'));
    expect(result.stderr, isEmpty);
    expect(result.exitCode, 0);
  });

  test('no such file', () async {
    p = project(mainSrc: "void main() { print('Hello World'); }");
    ProcessResult result =
        await p.run(['run', 'no/such/file/${p.relativeFilePath}']);

    expect(result.stderr, isNotEmpty);
    expect(result.exitCode, isNot(0));
  });

  test('implicit packageName.dart', () async {
    // TODO(jwren) circle back to reimplement this test if possible, the file
    // name (package name) will be the name of the temporary directory on disk
    p = project(mainSrc: "void main() { print('Hello World'); }");
    p.file('bin/main.dart', "void main() { print('Hello main.dart'); }");
    ProcessResult result = await p.run(['run']);

    expect(result.stdout, contains('Hello main.dart'));
    expect(result.stderr, isEmpty);
    expect(result.exitCode, 0);
  }, skip: true);

  // Could not find the implicit file to run: bin
  test('missing implicit packageName.dart', () async {
    p = project(mainSrc: "void main() { print('Hello World'); }");
    p.file('bin/foo.dart', "void main() { print('Hello main.dart'); }");
    ProcessResult result = await p.run(['run']);

    expect(result.stdout, isEmpty);
    expect(
        result.stderr,
        contains('Could not find `bin${path.separator}dartdev_temp.dart` in '
            'package `dartdev_temp`.'));
    expect(result.exitCode, 255);
  });

  test('arguments are properly passed', () async {
    p = project();
    p.file('main.dart', 'void main(args) { print(args); }');
    ProcessResult result = await p.run([
      'run',
      '--enable-experiment=test-experiment',
      'main.dart',
      'argument1',
      'argument2',
    ]);

    // --enable-experiment and main.dart should not be passed.
    expect(result.stdout, equals('[argument1, argument2]\n'));
    expect(result.stderr, isEmpty);
    expect(result.exitCode, 0);
  });

  test('from path-dependency with cyclic dependency', () async {
    p = project(name: 'foo');
    final bar = TestProject(name: 'bar');
    p.file('pubspec.yaml', '''
name: foo
environment:
  sdk: '>=2.9.0<3.0.0'

dependencies: { 'bar': {'path': '${bar.dir.path}'}}
''');
    p.file('lib/foo.dart', r'''
import 'package:bar/bar.dart';
final b = "FOO $bar";
''');

    try {
      bar.file('lib/bar.dart', 'final bar = "BAR";');

      bar.file('bin/main.dart', r'''
import 'package:foo/foo.dart';
void main(List<String> args) => print("$b $args");
''');

      ProcessResult result = await p.run(['run', 'bar:main', '--arg1', 'arg2']);

      expect(result.stderr, isEmpty);
      expect(result.stdout, contains('FOO BAR [--arg1, arg2]'));
      expect(result.exitCode, 0);
    } finally {
      await bar.dispose();
    }
  });

  test('with absolute file path', () async {
    p = project();
    p.file('main.dart', 'void main(args) { print(args); }');
    // Test with absolute path
    final name = path.join(p.dirPath, 'main.dart');
    final result = await p.run([
      'run',
      '--enable-experiment=test-experiment',
      name,
      '--argument1',
      'argument2',
    ]);

    // --enable-experiment and main.dart should not be passed.
    expect(result.stderr, isEmpty);
    expect(result.stdout, equals('[--argument1, argument2]\n'));
    expect(result.exitCode, 0);
  });

  test('with file uri', () async {
    p = project();
    p.file('main.dart', 'void main(args) { print(args); }');
    // Test with File uri
    final name = path.join(p.dirPath, 'main.dart');
    final result = await p.run([
      'run',
      Uri.file(name).toString(),
      '--argument1',
      'argument2',
    ]);

    // --enable-experiment and main.dart should not be passed.
    expect(result.stderr, isEmpty);
    expect(result.stdout, equals('[--argument1, argument2]\n'));
    expect(result.exitCode, 0);
  });

  test('with accepted VM flags', () async {
    p = project(mainSrc: "void main() { print('Hello World'); }");

    // --observe sets the following flags by default:
    //   --enable-vm-service
    //   --pause-isolate-on-exit
    //   --pause-isolate-on-unhandled-exception
    //   --warn-on-pause-with-no-debugger
    //
    // This test ensures that allowed arguments for dart run which are valid VM
    // arguments are properly handled by the VM.
    ProcessResult result = await p.run([
      'run',
      '--observe',
      '--pause-isolates-on-start',
      // This should negate the above flag.
      '--no-pause-isolates-on-start',
      '--no-pause-isolates-on-exit',
      '--no-pause-isolates-on-unhandled-exceptions',
      '-Dfoo=bar',
      '--define=bar=foo',
      p.relativeFilePath,
    ]);
    expect(
      result.stdout,
      matches(
          r'Observatory listening on http:\/\/127.0.0.1:8181\/[a-zA-Z0-9_-]+=\/\n.*'),
    );
    expect(result.stderr, isEmpty);
    expect(result.exitCode, 0);

    // Again, with --disable-service-auth-codes.
    result = await p.run([
      'run',
      '--observe',
      '--pause-isolates-on-start',
      // This should negate the above flag.
      '--no-pause-isolates-on-start',
      '--no-pause-isolates-on-exit',
      '--no-pause-isolates-on-unhandled-exceptions',
      '--disable-service-auth-codes',
      '-Dfoo=bar',
      '--define=bar=foo',
      p.relativeFilePath,
    ]);

    expect(
      result.stdout,
      contains('Observatory listening on http://127.0.0.1:8181/\n'),
    );
    expect(result.stderr, isEmpty);
    expect(result.exitCode, 0);

    // Again, with IPv6.
    result = await p.run([
      'run',
      '--observe=8181/::1',
      '--pause-isolates-on-start',
      // This should negate the above flag.
      '--no-pause-isolates-on-start',
      '--no-pause-isolates-on-exit',
      '--no-pause-isolates-on-unhandled-exceptions',
      '-Dfoo=bar',
      '--define=bar=foo',
      p.relativeFilePath,
    ]);

    expect(
      result.stdout,
      matches(
          r'Observatory listening on http:\/\/\[::1\]:8181\/[a-zA-Z0-9_-]+=\/\n.*'),
    );
    expect(result.stderr, isEmpty);
    expect(result.exitCode, 0);
  });

  test('fails when provided verbose VM flags', () async {
    p = project(mainSrc: "void main() { print('Hello World'); }");

    // Any VM flags not listed under 'dart run help --verbose' should be passed
    // before a dartdev command.
    ProcessResult result = await p.run([
      'run',
      '--vm-name=foo',
      p.relativeFilePath,
    ]);

    expect(result.stdout, isEmpty);
    expect(
      result.stderr,
      contains('Could not find an option named "vm-name".'),
    );
    expect(result.exitCode, 64);
  });

  test('fails when provided unlisted VM flags', () async {
    p = project(mainSrc: "void main() { print('Hello World'); }");

    // Any VM flags not listed under 'dart run help --verbose' should be passed
    // before a dartdev command.
    ProcessResult result = await p.run([
      'run',
      '--verbose_gc',
      p.relativeFilePath,
    ]);

    expect(result.stdout, isEmpty);
    expect(
      result.stderr,
      contains('Could not find an option named "verbose_gc".'),
    );
    expect(result.exitCode, 64);
  });

  test('--enable-asserts', () async {
    p = project(mainSrc: 'void main() { assert(false); }');

    // Ensure --enable-asserts doesn't cause the dartdev isolate to fail to
    // load. Regression test for: https://github.com/dart-lang/sdk/issues/42831
    ProcessResult result = await p.run([
      'run',
      '--enable-asserts',
      p.relativeFilePath,
    ]);

    expect(result.stdout, isEmpty);
    expect(result.stderr, contains('Unhandled exception'));
    expect(result.exitCode, 255);
  });

  test('does not interpret VM flags provided after script', () async {
    p = project(mainSrc: 'void main() { assert(false); }');

    // Any VM flags passed after the script shouldn't be interpreted by the VM.
    ProcessResult result = await p.run([
      'run',
      p.relativeFilePath,
      '--enable-asserts',
    ]);

    expect(result.stdout, isEmpty);
    expect(result.stderr, isEmpty);
    expect(result.exitCode, 0);
  });

  test('--enable-service-port-fallback', () async {
    final p = project(mainSrc: '''void main() {}''');
    final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
    final result = await p.run(
      [
        'run',
        '--enable-vm-service=${server.port}',
        '--enable-service-port-fallback',
        p.relativeFilePath,
      ],
    );
    final regexp = RegExp(
        r'Observatory listening on http:\/\/127.0.0.1:(\d*)\/[a-zA-Z0-9_-]+=\/\n.*');
    final vmServicePort =
        int.parse(regexp.firstMatch(result.stdout)!.group(1)!);
    expect(server.port != vmServicePort, isTrue);
    await server.close();
  });

  test('without verbose CFE info', () async {
    final p = project(mainSrc: '''void main() {}''');

    var result = await p.run(
      [
        'run',
        '--verbosity=warning',
        p.relativeFilePath,
      ],
    );

    expect(result.stdout,
        predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
    expect(result.stderr, isEmpty);
    expect(result.exitCode, 0);
  });

  group('DDS', () {
    group('disable', () {
      test('dart run simple', () async {
        p = project(mainSrc: "void main() { print('Hello World'); }");
        ProcessResult result = await p.run([
          'run',
          '--no-dds',
          '--enable-vm-service',
          p.relativeFilePath,
        ]);
        expect(result.stdout, isNot(contains(devToolsMessagePrefix)));
        expect(result.stdout, contains(observatoryMessagePrefix));
      });

      test('dart simple', () async {
        p = project(mainSrc: "void main() { print('Hello World'); }");
        ProcessResult result = await p.run([
          '--no-dds',
          '--enable-vm-service',
          p.relativeFilePath,
        ]);
        expect(result.stdout, isNot(contains(devToolsMessagePrefix)));
        expect(result.stdout, contains(observatoryMessagePrefix));
      });
    });

    group('explicit enable', () {
      test('dart run simple', () async {
        p = project(mainSrc: "void main() { print('Hello World'); }");
        ProcessResult result = await p.run([
          'run',
          '--dds',
          '--enable-vm-service',
          p.relativeFilePath,
        ]);
        expect(result.stdout, contains(devToolsMessagePrefix));
        expect(result.stdout, contains(observatoryMessagePrefix));
      });

      test('dart simple', () async {
        p = project(mainSrc: "void main() { print('Hello World'); }");
        ProcessResult result = await p.run([
          '--dds',
          '--enable-vm-service',
          p.relativeFilePath,
        ]);
        expect(result.stdout, contains(devToolsMessagePrefix));
        expect(result.stdout, contains(observatoryMessagePrefix));
      });
    });
  });

  group('DevTools', () {
    test('dart run simple', () async {
      p = project(mainSrc: "void main() { print('Hello World'); }");
      ProcessResult result = await p.run([
        'run',
        '--enable-vm-service',
        p.relativeFilePath,
      ]);
      expect(result.stdout, contains(devToolsMessagePrefix));
    });

    test('dart simple', () async {
      p = project(mainSrc: "void main() { print('Hello World'); }");
      ProcessResult result = await p.run([
        '--enable-vm-service',
        p.relativeFilePath,
      ]);
      expect(result.stdout, contains(devToolsMessagePrefix));
    });

    test('dart run explicit', () async {
      p = project(mainSrc: "void main() { print('Hello World'); }");
      ProcessResult result = await p.run([
        'run',
        '--serve-devtools',
        '--enable-vm-service',
        p.relativeFilePath,
      ]);
      expect(result.stdout, contains(devToolsMessagePrefix));
    });

    test('dart explicit', () async {
      p = project(mainSrc: "void main() { print('Hello World'); }");
      ProcessResult result = await p.run([
        '--serve-devtools',
        '--enable-vm-service',
        p.relativeFilePath,
      ]);
      expect(result.stdout, contains(devToolsMessagePrefix));
    });

    test('dart run disabled', () async {
      p = project(mainSrc: "void main() { print('Hello World'); }");
      ProcessResult result = await p.run([
        'run',
        '--enable-vm-service',
        '--no-serve-devtools',
        p.relativeFilePath,
      ]);
      expect(result.stdout, isNot(contains(devToolsMessagePrefix)));
    });

    test('dart disabled', () async {
      p = project(mainSrc: "void main() { print('Hello World'); }");
      ProcessResult result = await p.run([
        '--enable-vm-service',
        '--no-serve-devtools',
        p.relativeFilePath,
      ]);
      expect(result.stdout, isNot(contains(devToolsMessagePrefix)));
    });

    test('dart run VM service not enabled', () async {
      p = project(mainSrc: "void main() { print('Hello World'); }");
      ProcessResult result = await p.run([
        'run',
        '--serve-devtools',
        p.relativeFilePath,
      ]);
      expect(result.stdout, isNot(contains(devToolsMessagePrefix)));
    });

    test('dart VM service not enabled', () async {
      p = project(mainSrc: "void main() { print('Hello World'); }");
      ProcessResult result = await p.run([
        '--serve-devtools',
        p.relativeFilePath,
      ]);
      expect(result.stdout, isNot(contains(devToolsMessagePrefix)));
    });

    test(
      'spawn via SIGQUIT',
      () async {
        p = project(
          mainSrc:
              'void main() { print("ready"); int i = 0; while(true) { i++; } }',
        );
        Process process = await p.start([
          p.relativeFilePath,
        ]);

        final readyCompleter = Completer<void>();
        final completer = Completer<void>();

        late StreamSubscription sub;
        sub = process.stdout.transform(utf8.decoder).listen((event) async {
          if (event.contains('ready')) {
            readyCompleter.complete();
          } else if (event.contains(devToolsMessagePrefix)) {
            await sub.cancel();
            completer.complete();
          }
        });
        // Wait for process to start.
        await readyCompleter.future;
        process.kill(ProcessSignal.sigquit);
        await completer.future;
        process.kill();
      },
      // No support for SIGQUIT on Windows.
      skip: Platform.isWindows,
    );
  });
}
