// 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:io';

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

final executable = Platform.executable;

main() async {
  // Run the Dart VM with or without:
  //     --packages=<packages|package_config>
  final futures = <Future>[];
  for (final runWithPackagesArg in const [true, false]) {
    // Run the isolate with or without
    //    Isolate.spawnUri(..., packageConfig: <packages|package_config>)
    print('TEST runWithPackagesArg = $runWithPackagesArg ');
    for (final spawnWithPackageConfig in const [true, false]) {
      print('TEST spawnWithPackageConfig = $spawnWithPackageConfig ');
      final bool checkForResolveUri =
          runWithPackagesArg || !spawnWithPackageConfig;
      futures.add(runDotPackagesTest(
          runWithPackagesArg, spawnWithPackageConfig, checkForResolveUri));
      for (final optionalPackageUri in const [true, false]) {
        print('TEST optionalPackageUri = $optionalPackageUri');
        futures.add(runPackageConfigTest(runWithPackagesArg,
            spawnWithPackageConfig, optionalPackageUri, checkForResolveUri));
      }
    }
  }
  await Future.wait(futures);
}

Future runPackageConfigTest(bool withPackagesArg, bool spawnWithArg,
    bool optionalPackageUri, bool checkForResolveUri) async {
  await withApplicationDirAndDotDartToolPackageConfig(
      (String tempDir, String packageJson, String mainFile) async {
    final args = [if (withPackagesArg) '--packages=$packageJson', mainFile];
    await run(executable, args);
  }, spawnWithArg, optionalPackageUri, checkForResolveUri);
}

Future runDotPackagesTest(
    bool withPackagesArg, bool spawnWithArg, bool checkForResolveUri) async {
  await withApplicationDirAndDotPackages(
      (String tempDir, String dotPackagesFile, String mainFile) async {
    final args = [
      if (withPackagesArg) '--packages=$dotPackagesFile',
      mainFile,
    ];
    await run(executable, args);
  }, spawnWithArg, checkForResolveUri);
}

Future withApplicationDirAndDotPackages(
    Future fn(String tempDir, String packagesDir, String mainFile),
    bool spawnWithArg,
    bool checkForResolveUri) async {
  await withTempDir((String tempDir) async {
    // Setup ".packages"
    final dotPackagesFile =
        path.join(tempDir, spawnWithArg ? 'baz.packages' : '.packages');
    await File(dotPackagesFile).writeAsString(buildDotPackages('foo'));

    final mainFile = path.join(tempDir, 'main.dart');
    final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
    final importUri = 'package:foo/child_isolate.dart';
    await File(childIsolateFile).writeAsString(buildChildIsolate());
    await File(mainFile).writeAsString(buildMainIsolate(
        importUri,
        spawnWithArg ? dotPackagesFile : null,
        checkForResolveUri ? childIsolateFile : null));

    await fn(tempDir, dotPackagesFile, mainFile);
  });
}

Future withApplicationDirAndDotDartToolPackageConfig(
    Future fn(String tempDir, String packageJson, String mainFile),
    bool spawnWithArg,
    bool optionalPackageUri,
    bool checkForResolveUri) async {
  await withTempDir((String tempDir) async {
    // Setup ".dart_tool/package_config.json"
    final dotDartToolDir = path.join(tempDir, '.dart_tool');
    await Directory(dotDartToolDir).create();
    final packageConfigJsonFile = path.join(
        dotDartToolDir, spawnWithArg ? 'baz.packages' : 'package_config.json');
    await File(packageConfigJsonFile)
        .writeAsString(buildPackageConfig('foo', optionalPackageUri));

    // Setup actual application
    final mainFile = path.join(tempDir, 'main.dart');
    final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
    final importUri = 'package:foo/child_isolate.dart';
    await File(childIsolateFile).writeAsString(buildChildIsolate());
    await File(mainFile).writeAsString(buildMainIsolate(
        importUri,
        spawnWithArg ? packageConfigJsonFile : null,
        checkForResolveUri ? childIsolateFile : null));

    await fn(tempDir, packageConfigJsonFile, mainFile);
  });
}

Future withTempDir(Future fn(String dir)) async {
  final dir = await Directory.systemTemp.createTemp('spawn_uri');
  try {
    await fn(dir.absolute.path);
  } finally {
    await dir.delete(recursive: true);
  }
}

Future<ProcessResult> run(String executable, List<String> args,
    {String? cwd}) async {
  print('Running $executable ${args.join(' ')}');
  final String workingDirectory = cwd ?? Directory.current.absolute.path;
  final result = await Process.run(executable, ['--trace-loading', ...args],
      workingDirectory: workingDirectory);
  print('exitCode:\n${result.exitCode}');
  print('stdout:\n${result.stdout}');
  print('stdout:\n${result.stderr}');
  Expect.equals(0, result.exitCode);
  return result;
}

String buildDotPackages(String packageName) => '$packageName:.';

String buildPackageConfig(String packageName, bool optionalPackageUri) => '''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "$packageName",
      "rootUri": "../"
      ${optionalPackageUri ? ', "packageUri": "./"' : ''}
    }
  ]
}
''';

String buildChildIsolate() => '''
  import 'dart:isolate';

  main(List<String> args, SendPort message) {
    message.send('child isolate is done');
  }
''';

String buildMainIsolate(
        String spawnUri, String? packageConfigUri, String? childIsolatePath) =>
    '''
  import 'dart:isolate';
  import 'dart:io' as io;

  main(List<String> args) async {
    io.exitCode = 1;

    final uri = Uri.parse('$spawnUri');
    final resolvedUri = await Isolate.resolvePackageUri(uri);
    if ("""\${resolvedUri?.toFilePath()}""" != r"""$childIsolatePath""") {
      throw 'Could not Isolate.resolvePackageUri(uri).';
    }

    final rp = ReceivePort();
    final isolateArgs = <String>['a'];
    await Isolate.spawnUri(
        uri,
        isolateArgs,
        rp.sendPort,
        packageConfig: ${packageConfigUri != null ? 'Uri.file(r"$packageConfigUri")' : 'null'});
    final childIsolateMessage = await rp.first;
    if (childIsolateMessage != 'child isolate is done') {
      throw 'Did not receive correct message from child isolate.';
    }

    // Test was successful.
    io.exitCode = 0;
  }
''';
