// 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))
library;

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

import 'package:io/io.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart';
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.
  const debug = false;

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

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

    await process.shouldExit(0);

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

  tearDownAll(testRunner.tearDownAll);

  test('smoke test is configured properly', () async {
    final smokeYaml =
        loadYaml(await File('$exampleDirectory/pubspec.yaml').readAsString())
            as YamlMap;
    final webdevYaml =
        loadYaml(await File('pubspec.yaml').readAsString()) as YamlMap;
    expect(smokeYaml['environment']['sdk'],
        equals(webdevYaml['environment']['sdk']));
    expect(
        buildRunnerConstraint.allowsAny(VersionConstraint.parse(
            smokeYaml['dev_dependencies']['build_runner'])),
        true);
    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();

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

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

    // 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 ${d.sandbox}. '
          '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 {
      final args = [
        'build',
        '-o',
        'web:${d.sandbox}',
        '--',
        '--delete-conflicting-outputs'
      ];

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

      await checkProcessStdout(process, ['Built with build_runner']);
      await process.shouldExit(0);
    },
    // https://github.com/dart-lang/webdev/issues/2489,
    skip: Platform.isWindows,
  );

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

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

          final expectedItems = <Object>['Built with build_runner'];

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

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

            if (shouldExist) {
              await d.file(entry.key, isNotEmpty).validate();
            } else {
              await d.nothing(entry.key).validate();
            }
          }
        },
        // https://github.com/dart-lang/webdev/issues/2489
        skip: Platform.isWindows,
      );
    }
    test(
      'and --null-safety=sound',
      () async {
        final args = [
          'build',
          '-o',
          'web:${d.sandbox}',
          '--no-release',
          '--null-safety=sound'
        ];

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

        final expectedItems = <Object>['Built with build_runner'];

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

        await d.file('main.ddc.js', isNotEmpty).validate();
      },
      // https://github.com/dart-lang/webdev/issues/2489
      skip: Platform.isWindows,
    );
  });

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

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

        final expectedItems = <Object>['Built with build_runner'];

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

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

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

        final stdoutDone = Completer<void>();
        final stderrDone = Completer<void>();
        final process = await testRunner.runWebDev(args,
            workingDirectory: exampleDirectory);
        process.stdoutStream().listen((_) => {}, onDone: stdoutDone.complete);
        process.stderrStream().listen((_) => {}, onDone: stderrDone.complete);

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

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

        final client = HttpClient();

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

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

            final 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();
        await Future.wait([stdoutDone.future, stderrDone.future]);
      });
    }
  });

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

          final process = await testRunner.runWebDev(args,
              workingDirectory: exampleDirectory);
          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);
    });
    group('and --enable-expression-evaluation:', () {
      setUp(() async {
        configureLogWriter(debug);
      });
      test('evaluateInFrame', () async {
        final openPort = await findUnusedPort();
        // running daemon command that starts dwds without keyboard input
        final args = [
          'daemon',
          'web:$openPort',
          '--enable-expression-evaluation',
          '--null-safety=sound',
          '--verbose',
        ];
        final process = await testRunner.runWebDev(args,
            workingDirectory: 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!);
          final vm = await vmService.getVM();
          final isolateId = vm.isolates!.first.id!;
          final scripts = await vmService.getScripts(isolateId);

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

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

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

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

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

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

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

      test('evaluate', () async {
        final openPort = await findUnusedPort();
        // running daemon command that starts dwds without keyboard input
        final args = [
          'daemon',
          'web:$openPort',
          '--enable-expression-evaluation',
          '--verbose',
        ];
        final process = await testRunner.runWebDev(args,
            workingDirectory: 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!);
          final vm = await vmService.getVM();
          final isolateId = vm.isolates!.first.id!;
          final isolate = await vmService.getIsolate(isolateId);
          final 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, 'topLevelMethod()');

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

      test('evaluate and get objects', () async {
        final openPort = await findUnusedPort();
        // running daemon command that starts dwds without keyboard input
        final args = [
          'daemon',
          'web:$openPort',
          '--enable-expression-evaluation',
          '--verbose',
        ];
        final process = await testRunner.runWebDev(args,
            workingDirectory: 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!);
          final vm = await vmService.getVM();
          final isolateId = vm.isolates!.first.id!;
          final isolate = await vmService.getIsolate(isolateId);
          final 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 {
        final openPort = await findUnusedPort();
        final args = [
          'daemon',
          'web:$openPort',
          '--no-enable-expression-evaluation',
          '--verbose',
        ];
        final process = await testRunner.runWebDev(args,
            workingDirectory: 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!);
          final vm = await vmService.getVM();
          final isolateId = vm.isolates!.first.id!;
          final scripts = await vmService.getScripts(isolateId);

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

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

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

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

          final 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 {
        final openPort = await findUnusedPort();
        // running daemon command that starts dwds without keyboard input
        final args = [
          'daemon',
          'web:$openPort',
          '--no-enable-expression-evaluation',
          '--verbose',
        ];
        final process = await testRunner.runWebDev(args,
            workingDirectory: 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!);
          final vm = await vmService.getVM();
          final isolateId = vm.isolates!.first.id!;
          final isolate = await vmService.getIsolate(isolateId);
          final libraryId = isolate.rootLib!.id!;

          await vmService.streamListen('Debug');

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