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

@Timeout(Duration(minutes: 5))
import 'dart:io';

import 'package:io/io.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:test_common/utilities.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
import 'package:test_process/test_process.dart';
import 'package:vm_service/vm_service.dart';
import 'package:vm_service/vm_service_io.dart';
import 'package:webdev/src/logging.dart';
import 'package:webdev/src/pubspec.dart';
import 'package:webdev/src/serve/utils.dart';
import 'package:webdev/src/util.dart';
import 'package:yaml/yaml.dart';

import 'daemon/utils.dart';
import 'test_utils.dart';

/// Key: name of file in web directory
/// Value: `null`  - exists in both modes
///        `true`  - DDC only
///        `false` - dart2js only
final _testItems = <String, bool?>{
  'main.dart.js': null,
  'main.dart.bootstrap.js': true,
  'main.ddc.js': true,
};

void main() {
  // Change to true for debugging.
  final debug = false;

  final testRunner = TestRunner();
  late String exampleDirectory;
  late String soundExampleDirectory;
  setUpAll(() async {
    configureLogWriter(debug);
    await testRunner.setUpAll();
    exampleDirectory =
        p.absolute(p.join(p.current, '..', 'fixtures', '_webdevSmoke'));
    soundExampleDirectory =
        p.absolute(p.join(p.current, '..', 'fixtures', '_webdevSoundSmoke'));

    var process = await TestProcess.start(dartPath, ['pub', 'upgrade'],
        workingDirectory: exampleDirectory, environment: getPubEnvironment());

    await process.shouldExit(0);

    process = await TestProcess.start(dartPath, ['pub', 'upgrade'],
        workingDirectory: soundExampleDirectory,
        environment: getPubEnvironment());

    await process.shouldExit(0);

    await d
        .file('.dart_tool/package_config.json', isNotEmpty)
        .validate(soundExampleDirectory);
    await d.file('pubspec.lock', isNotEmpty).validate(soundExampleDirectory);
  });

  tearDownAll(testRunner.tearDownAll);

  test('smoke test is configured properly', () async {
    var smokeYaml = loadYaml(
            await File('$soundExampleDirectory/pubspec.yaml').readAsString())
        as YamlMap;
    var webdevYaml =
        loadYaml(await File('pubspec.yaml').readAsString()) as YamlMap;
    expect(smokeYaml['environment']['sdk'],
        equals(webdevYaml['environment']['sdk']));
    expect(smokeYaml['dev_dependencies']['build_runner'],
        equals(buildRunnerConstraint.toString()));
    expect(smokeYaml['dev_dependencies']['build_web_compilers'],
        equals(buildWebCompilersConstraint.toString()));
  });

  test('build should fail if targeting an existing directory', () async {
    await d.file('simple thing', 'throw-away').create();

    var args = ['build', '-o', 'web:${d.sandbox}'];

    var process = await testRunner.runWebDev(args,
        workingDirectory: soundExampleDirectory);

    // NOTE: We'd like this to be more useful
    // See https://github.com/dart-lang/build/issues/1283

    await expectLater(
        process.stdout,
        emitsThrough(
            contains('Unable to create merged directory at ${d.sandbox}.')));
    await expectLater(
        process.stdout,
        emitsThrough(
            'Choose a different directory or delete the contents of that '
            'directory.'));

    await process.shouldExit(isNot(0));
  });

  test('build should allow passing extra arguments to build_runner', () async {
    var args = [
      'build',
      '-o',
      'web:${d.sandbox}',
      '--',
      '--delete-conflicting-outputs'
    ];

    var process = await testRunner.runWebDev(args,
        workingDirectory: soundExampleDirectory);

    await checkProcessStdout(process, ['Succeeded']);
    await process.shouldExit(0);
  });

  group('should build with valid configuration', () {
    for (var withDDC in [true, false]) {
      test(withDDC ? 'DDC' : 'dart2js', () async {
        var args = ['build', '-o', 'web:${d.sandbox}'];
        if (withDDC) {
          args.add('--no-release');
        }

        var process = await testRunner.runWebDev(args,
            workingDirectory: soundExampleDirectory);

        var expectedItems = <Object>['Succeeded'];

        await checkProcessStdout(process, expectedItems);
        await process.shouldExit(0);

        for (var entry in _testItems.entries) {
          var shouldExist = (entry.value ?? withDDC) == withDDC;

          if (shouldExist) {
            await d.file(entry.key, isNotEmpty).validate();
          } else {
            await d.nothing(entry.key).validate();
          }
        }
      });
    }
    test('and --null-safety=sound', () async {
      var args = [
        'build',
        '-o',
        'web:${d.sandbox}',
        '--no-release',
        '--null-safety=sound'
      ];

      var process = await testRunner.runWebDev(args,
          workingDirectory: soundExampleDirectory);

      var expectedItems = <Object>['Succeeded'];

      await checkProcessStdout(process, expectedItems);
      await process.shouldExit(0);

      await d.file('main.ddc.js', isNotEmpty).validate();
    });

    test('and --null-safety=unsound', () async {
      var args = [
        'build',
        '-o',
        'web:${d.sandbox}',
        '--no-release',
        '--null-safety=unsound'
      ];

      var process =
          await testRunner.runWebDev(args, workingDirectory: exampleDirectory);

      var expectedItems = <Object>['Succeeded'];

      await checkProcessStdout(process, expectedItems);
      await process.shouldExit(0);

      await d.file('main.unsound.ddc.js', isNotEmpty).validate();
    });
  });

  group('should build with --output=NONE', () {
    for (var withDDC in [true, false]) {
      test(withDDC ? 'DDC' : 'dart2js', () async {
        var args = ['build', '--output=NONE'];
        if (withDDC) {
          args.add('--no-release');
        }

        var process = await testRunner.runWebDev(args,
            workingDirectory: soundExampleDirectory);

        var expectedItems = <Object>['Succeeded'];

        await checkProcessStdout(process, expectedItems);
        await process.shouldExit(0);

        await d.nothing('build').validate(soundExampleDirectory);
      });
    }
  });

  group('should serve with valid configuration', () {
    for (var withDDC in [true, false]) {
      var type = withDDC ? 'DDC' : 'dart2js';
      test('using $type', () async {
        var openPort = await findUnusedPort();
        var args = ['serve', 'web:$openPort'];
        if (!withDDC) {
          args.add('--release');
        }

        var process = await testRunner.runWebDev(args,
            workingDirectory: soundExampleDirectory);

        var hostUrl = 'http://localhost:$openPort';

        // Wait for the initial build to finish.
        await expectLater(process.stdout, emitsThrough(contains('Succeeded')));

        var client = HttpClient();

        try {
          for (var entry in _testItems.entries) {
            var url = Uri.parse('$hostUrl/${entry.key}');

            var request = await client.getUrl(url);
            var response = await request.close();

            var shouldExist = (entry.value ?? withDDC) == withDDC;

            expect(response.statusCode, shouldExist ? 200 : 404,
                reason: 'Expecting "$url"? $shouldExist');
          }
        } finally {
          client.close(force: true);
        }

        await process.kill();
        await process.shouldExit();
      });
    }
  });

  group('Should fail with invalid build directories', () {
    var invalidServeDirs = ['.', '../', '../foo', 'foo/bar', 'foo/../'];
    for (var dir in invalidServeDirs) {
      for (var command in ['build', 'serve']) {
        test('cannot $command directory: `$dir`', () async {
          var args = [
            command,
            if (command == 'build') '--output=$dir:foo' else dir
          ];

          var process = await testRunner.runWebDev(args,
              workingDirectory: soundExampleDirectory);
          await expectLater(
              process.stdout,
              emitsThrough(contains(
                  'Invalid configuration: Only top level directories under the '
                  'package can be built')));
          await expectLater(process.exitCode, completion(ExitCode.config.code));
        });
      }
    }
  });

  group('should work with ', () {
    setUp(() async {
      configureLogWriter(debug);
    });

    for (var soundNullSafety in [false, true]) {
      var nullSafetyOption = soundNullSafety ? 'sound' : 'unsound';
      group('--null-safety=$nullSafetyOption', () {
        setUp(() async {
          configureLogWriter(debug);
        });
        group('and --enable-expression-evaluation:', () {
          setUp(() async {
            configureLogWriter(debug);
          });
          test('evaluateInFrame', () async {
            var openPort = await findUnusedPort();
            // running daemon command that starts dwds without keyboard input
            var args = [
              'daemon',
              'web:$openPort',
              '--enable-expression-evaluation',
              '--null-safety=$nullSafetyOption',
              '--verbose',
            ];
            var process = await testRunner.runWebDev(args,
                workingDirectory:
                    soundNullSafety ? soundExampleDirectory : exampleDirectory);
            VmService? vmService;

            process.stdoutStream().listen(Logger.root.fine);
            process.stderrStream().listen(Logger.root.warning);

            try {
              // Wait for debug service Uri
              String? wsUri;
              await expectLater(process.stdout, emitsThrough((message) {
                wsUri = getDebugServiceUri(message as String);
                return wsUri != null;
              }));
              Logger.root.fine('vm service uri: $wsUri');
              expect(wsUri, isNotNull);

              vmService = await vmServiceConnectUri(wsUri!);
              var vm = await vmService.getVM();
              var isolateId = vm.isolates!.first.id!;
              var scripts = await vmService.getScripts(isolateId);

              await vmService.streamListen('Debug');
              var stream = vmService.onEvent('Debug');

              var mainScript = scripts.scripts!
                  .firstWhere((each) => each.uri!.contains('main.dart'));

              var bpLine = await findBreakpointLine(
                  vmService, 'printCounter', isolateId, mainScript);

              var bp = await vmService.addBreakpointWithScriptUri(
                  isolateId, mainScript.uri!, bpLine);
              expect(bp, isNotNull);

              await stream.firstWhere(
                  (Event event) => event.kind == EventKind.kPauseBreakpoint);

              final isNullSafetyEnabled =
                  '() { const sound = !(<Null>[] is List<int>); return sound; } ()';
              final result = await vmService.evaluateInFrame(
                  isolateId, 0, isNullSafetyEnabled);

              expect(
                  result,
                  const TypeMatcher<InstanceRef>().having(
                      (instance) => instance.valueAsString,
                      'valueAsString',
                      '$soundNullSafety'));
            } finally {
              await vmService?.dispose();
              await exitWebdev(process);
              await process.shouldExit();
            }
          }, timeout: const Timeout.factor(2));

          test('evaluate', () async {
            var openPort = await findUnusedPort();
            // running daemon command that starts dwds without keyboard input
            var args = [
              'daemon',
              'web:$openPort',
              '--enable-expression-evaluation',
              '--verbose',
            ];
            var process = await testRunner.runWebDev(args,
                workingDirectory:
                    soundNullSafety ? soundExampleDirectory : exampleDirectory);

            process.stdoutStream().listen(Logger.root.fine);
            process.stderrStream().listen(Logger.root.warning);

            VmService? vmService;

            try {
              // Wait for debug service Uri
              String? wsUri;
              await expectLater(process.stdout, emitsThrough((message) {
                wsUri = getDebugServiceUri(message as String);
                return wsUri != null;
              }));
              expect(wsUri, isNotNull);

              vmService = await vmServiceConnectUri(wsUri!);
              var vm = await vmService.getVM();
              var isolateId = vm.isolates!.first.id!;
              var isolate = await vmService.getIsolate(isolateId);
              var libraryId = isolate.rootLib!.id!;

              await vmService.streamListen('Debug');

              var result = await vmService.evaluate(isolateId, libraryId,
                  '(document?.body?.children?.first as SpanElement)?.text');

              expect(
                  result,
                  const TypeMatcher<InstanceRef>().having(
                      (instance) => instance.valueAsString,
                      'valueAsString',
                      'Hello World!!'));

              result = await vmService.evaluate(
                  isolateId, libraryId, 'main.toString()');

              expect(
                  result,
                  const TypeMatcher<InstanceRef>().having(
                      (instance) => instance.valueAsString,
                      'valueAsString',
                      contains('Hello World!!')));
            } finally {
              await vmService?.dispose();
              await exitWebdev(process);
              await process.shouldExit();
            }
          }, timeout: const Timeout.factor(2));

          test('evaluate and get objects', () async {
            var openPort = await findUnusedPort();
            // running daemon command that starts dwds without keyboard input
            var args = [
              'daemon',
              'web:$openPort',
              '--enable-expression-evaluation',
              '--verbose',
            ];
            var process = await testRunner.runWebDev(args,
                workingDirectory:
                    soundNullSafety ? soundExampleDirectory : exampleDirectory);

            process.stdoutStream().listen(Logger.root.fine);
            process.stderrStream().listen(Logger.root.warning);

            VmService? vmService;

            try {
              // Wait for debug service Uri
              String? wsUri;
              await expectLater(process.stdout, emitsThrough((message) {
                wsUri = getDebugServiceUri(message as String);
                return wsUri != null;
              }));
              expect(wsUri, isNotNull);

              vmService = await vmServiceConnectUri(wsUri!);
              var vm = await vmService.getVM();
              var isolateId = vm.isolates!.first.id!;
              var isolate = await vmService.getIsolate(isolateId);
              var libraryId = isolate.rootLib!.id!;

              await vmService.streamListen('Debug');

              final result = await vmService.evaluate(
                  isolateId, libraryId, '[true, false]');
              expect(
                  result,
                  const TypeMatcher<InstanceRef>().having(
                      (instance) => instance.classRef?.name,
                      'class name',
                      dartSdkIsAtLeast('3.3.0-242.0.dev')
                          ? 'JSArray<bool>'
                          : 'List<bool>'));

              final instanceRef = result as InstanceRef;
              final list =
                  await vmService.getObject(isolateId, instanceRef.id!);
              expect(
                  list,
                  const TypeMatcher<Instance>().having(
                      (instance) => instance.classRef?.name,
                      'class name',
                      dartSdkIsAtLeast('3.3.0-242.0.dev')
                          ? 'JSArray<bool>'
                          : 'List<bool>'));

              final elements = (list as Instance).elements;
              expect(elements, [
                const TypeMatcher<InstanceRef>().having(
                    (instance) => instance.valueAsString, 'value', 'true'),
                const TypeMatcher<InstanceRef>().having(
                    (instance) => instance.valueAsString, 'value', 'false'),
              ]);
            } finally {
              await vmService?.dispose();
              await exitWebdev(process);
              await process.shouldExit();
            }
          }, timeout: const Timeout.factor(2));
        });

        group('and --no-enable-expression-evaluation:', () {
          test('evaluateInFrame', () async {
            var openPort = await findUnusedPort();
            var args = [
              'daemon',
              'web:$openPort',
              '--no-enable-expression-evaluation',
              '--verbose',
            ];
            var process = await testRunner.runWebDev(args,
                workingDirectory:
                    soundNullSafety ? soundExampleDirectory : exampleDirectory);
            VmService? vmService;

            try {
              // Wait for debug service Uri
              String? wsUri;
              await expectLater(process.stdout, emitsThrough((message) {
                wsUri = getDebugServiceUri(message as String);
                return wsUri != null;
              }));
              expect(wsUri, isNotNull);

              vmService = await vmServiceConnectUri(wsUri!);
              var vm = await vmService.getVM();
              var isolateId = vm.isolates!.first.id!;
              var scripts = await vmService.getScripts(isolateId);

              await vmService.streamListen('Debug');
              var stream = vmService.onEvent('Debug');

              var mainScript = scripts.scripts!
                  .firstWhere((each) => each.uri!.contains('main.dart'));

              var bpLine = await findBreakpointLine(
                  vmService, 'printCounter', isolateId, mainScript);

              var bp = await vmService.addBreakpointWithScriptUri(
                  isolateId, mainScript.uri!, bpLine);
              expect(bp, isNotNull);

              var event = await stream.firstWhere(
                  (Event event) => event.kind == EventKind.kPauseBreakpoint);

              expect(
                  () => vmService!.evaluateInFrame(
                      isolateId, event.topFrame!.index!, 'true'),
                  throwsRPCError);
            } finally {
              await vmService?.dispose();
              await exitWebdev(process);
              await process.shouldExit();
            }
          });

          test('evaluate', () async {
            var openPort = await findUnusedPort();
            // running daemon command that starts dwds without keyboard input
            var args = [
              'daemon',
              'web:$openPort',
              '--no-enable-expression-evaluation',
              '--verbose',
            ];
            var process = await testRunner.runWebDev(args,
                workingDirectory:
                    soundNullSafety ? soundExampleDirectory : exampleDirectory);
            VmService? vmService;

            try {
              // Wait for debug service Uri
              String? wsUri;
              await expectLater(process.stdout, emitsThrough((message) {
                wsUri = getDebugServiceUri(message as String);
                return wsUri != null;
              }));
              expect(wsUri, isNotNull);

              vmService = await vmServiceConnectUri(wsUri!);
              var vm = await vmService.getVM();
              var isolateId = vm.isolates!.first.id!;
              var isolate = await vmService.getIsolate(isolateId);
              var libraryId = isolate.rootLib!.id!;

              await vmService.streamListen('Debug');

              expect(
                  () => vmService!
                      .evaluate(isolateId, libraryId, 'main.toString()'),
                  throwsRPCError);
            } finally {
              await vmService?.dispose();
              await exitWebdev(process);
              await process.shouldExit();
            }
          }, timeout: const Timeout.factor(2));
        });
      });
    }
  });
}
