// Copyright (c) 2022, 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:_fe_analyzer_shared/src/macros/executor/isolated_executor.dart'
    as isolatedExecutor;
import 'package:_fe_analyzer_shared/src/macros/executor/serialization.dart';
import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/experimental_flags.dart';
import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart';
import 'package:front_end/src/api_prototype/memory_file_system.dart';
import 'package:front_end/src/base/processed_options.dart';
import 'package:front_end/src/compute_platform_binaries_location.dart';
import 'package:front_end/src/fasta/compiler_context.dart';
import 'package:front_end/src/fasta/hybrid_file_system.dart';
import 'package:front_end/src/fasta/incremental_compiler.dart';
import 'package:front_end/src/fasta/kernel/macro.dart';
import 'package:front_end/src/isolate_macro_serializer.dart';
import 'package:front_end/src/macro_serializer.dart';
import 'package:front_end/src/testing/compiler_common.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/target/targets.dart';
import 'package:kernel/text/ast_to_text.dart';
import 'package:vm/target/vm.dart';

import '../../utils/kernel_chain.dart';

Future<void> main(List<String> args) async {
  Map<String, Test> tests = {};
  Map<String, Map<Uri, Map<int, String>>> testData = {};
  Directory dataDir =
      new Directory.fromUri(Platform.script.resolve('data/tests'));

  void addFile(Test? test, FileSystemEntity file, String fileName) {
    if (file is! File || !fileName.endsWith('.dart')) {
      return;
    }
    String testFileName = fileName.substring(0, fileName.length - 5);
    int dotIndex = testFileName.lastIndexOf('.');
    int index = 1;
    if (dotIndex != -1) {
      index = int.parse(testFileName.substring(dotIndex + 1));
      testFileName = testFileName.substring(0, dotIndex);
    }
    String testName = testFileName;
    testFileName += '.dart';
    Uri uri = toTestUri(testFileName);
    test ??= new Test(testName, uri);
    tests[test.name] ??= test;
    Map<Uri, Map<int, String>> updates = testData[test.name] ??= {};
    (updates[uri] ??= {})[index] = file.readAsStringSync();
  }

  for (FileSystemEntity file in dataDir.listSync()) {
    String fileName = file.uri.pathSegments.last;
    if (file is Directory) {
      Directory dir = file;
      // Note that the last segment of a directory uri is the empty string!
      String dirName = dir.uri.pathSegments[dir.uri.pathSegments.length - 2];
      Test test = new Test('$dirName/main', toTestUri('$dirName/main.dart'));
      for (FileSystemEntity file in dir.listSync()) {
        addFile(test, file, '$dirName/${file.uri.pathSegments.last}');
      }
    } else {
      addFile(null, file, fileName);
    }
  }

  testData.forEach((String testName, Map<Uri, Map<int, String>> files) {
    Test test = tests[testName]!;
    Map<int, Map<Uri, String>> updatesMap = {};
    files.forEach((Uri uri, Map<int, String> updates) {
      test.uris.add(uri);
      updates.forEach((int index, String source) {
        (updatesMap[index] ??= {})[uri] = source;
      });
    });
    for (int index in updatesMap.keys.toList()..sort()) {
      test.updates.add(new TestUpdate(index, updatesMap[index]!));
    }
  });

  args = args.toList();
  bool generateExpectations = args.remove('-g');
  enableMacros = true;
  MacroSerializer macroSerializer = new IsolateMacroSerializer();
  MemoryFileSystem memoryFileSystem = createMemoryFileSystem();
  CompilerOptions compilerOptions = new CompilerOptions()
    ..sdkRoot = computePlatformBinariesLocation(forceBuildDir: true)
    ..packagesFileUri = Platform.script.resolve('data/package_config.json')
    ..explicitExperimentalFlags = {
      ExperimentalFlag.macros: true,
      ExperimentalFlag.alternativeInvalidationStrategy: true,
    }
    ..macroSerializer = macroSerializer
    ..precompiledMacroUris = {}
    ..macroExecutorProvider = () async {
      return await isolatedExecutor.start(SerializationMode.byteDataServer);
    }
    ..macroTarget = new VmTarget(new TargetFlags())
    ..fileSystem = new HybridFileSystem(memoryFileSystem);

  ProcessedOptions processedOptions =
      new ProcessedOptions(options: compilerOptions);

  await CompilerContext.runWithOptions(processedOptions,
      (CompilerContext context) async {
    IncrementalCompiler compiler = new IncrementalCompiler(context);
    for (Test test in tests.values) {
      if (args.isNotEmpty && !args.contains(test.name)) {
        print('Skipped ${test.name}');
        continue;
      }
      Uri entryPoint = test.entryPoint;
      for (TestUpdate update in test.updates) {
        print('Running ${test.name} update ${update.index}');
        update.files.forEach((Uri uri, String source) {
          memoryFileSystem.entityForUri(uri).writeAsStringSync(source);
          compiler.invalidate(uri);
        });
        IncrementalCompilerResult incrementalCompilerResult =
            await compiler.computeDelta(entryPoints: [entryPoint]);
        Component component = incrementalCompilerResult.component;
        StringBuffer buffer = new StringBuffer();
        Printer printer = new Printer(buffer)
          ..writeProblemsAsJson(
              "Problems in component", component.problemsAsJson);
        component.libraries.forEach((Library library) {
          if (test.uris.contains(library.importUri)) {
            printer.writeLibraryFile(library);
            printer.endLine();
          }
        });
        printer.writeConstantTable(component);
        String actual = buffer.toString();
        String expectationFileName = '${test.name}.${update.index}.dart.expect';
        Uri expectedUri = dataDir.uri.resolve(expectationFileName);
        File expectationFile = new File.fromUri(expectedUri);
        if (expectationFile.existsSync()) {
          String expected = expectationFile.readAsStringSync();
          if (expected != actual) {
            if (generateExpectations) {
              expectationFile.writeAsStringSync(actual);
            } else {
              String diff = await runDiff(expectedUri, actual);
              throw "${expectationFileName} don't match ${expectedUri}\n$diff";
            }
          }
        } else if (generateExpectations) {
          expectationFile.writeAsStringSync(actual);
        } else {
          throw 'Please use -g option to create file ${expectationFileName} '
              'with this content:\n$actual';
        }
      }
    }
  }, errorOnMissingInput: false);
  await macroSerializer.close();
}

class Test {
  final String name;
  final Uri entryPoint;
  final Set<Uri> uris = {};
  final List<TestUpdate> updates = [];

  Test(this.name, this.entryPoint);
}

class TestUpdate {
  final int index;
  final Map<Uri, String> files;

  TestUpdate(this.index, this.files);
}
