// Copyright (c) 2023, 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' show File;

import 'package:dev_compiler/src/command/command.dart';
import 'package:dev_compiler/src/command/options.dart' show Options;
import 'package:dev_compiler/src/compiler/module_builder.dart';
import 'package:dev_compiler/src/kernel/compiler.dart' show ProgramCompiler;
import 'package:dev_compiler/src/kernel/compiler_new.dart'
    show LibraryBundleCompiler;
import 'package:dev_compiler/src/kernel/expression_compiler.dart'
    show ExpressionCompiler;
import 'package:dev_compiler/src/kernel/module_metadata.dart';
import 'package:front_end/src/api_unstable/ddc.dart' as fe;
import 'package:kernel/ast.dart' show Component, Library;
import 'package:path/path.dart' as p;
import 'package:source_maps/source_maps.dart' as source_maps;

import '../shared_test_options.dart';

class TestCompilationResult {
  final String? result;
  final bool isSuccess;

  TestCompilationResult(this.result, this.isSuccess);
}

class TestExpressionCompiler {
  final SetupCompilerOptions setup;
  final Component component;
  final ExpressionCompiler compiler;
  final ModuleMetadata? metadata;
  final source_maps.SingleMapping sourceMap;

  TestExpressionCompiler._(
      this.setup, this.component, this.compiler, this.metadata, this.sourceMap);

  static Future<TestExpressionCompiler> init(SetupCompilerOptions setup,
      {required Uri input,
      required Uri output,
      Uri? packages,
      Map<String, bool> experiments = const {}}) async {
    setup.diagnosticMessages.clear();
    setup.errors.clear();
    // Initialize the incremental compiler and module component.
    // TODO: extend this for multi-module compilations by storing separate
    // compilers/components/names per module.
    setup.options.packagesFileUri = packages;
    setup.options.explicitExperimentalFlags.addAll(fe.parseExperimentalFlags(
        experiments,
        onError: (message) => throw Exception(message)));
    var frontend = DevelopmentIncrementalCompiler(setup.options, input);
    var compilerResult = await frontend.computeDelta();
    var component = compilerResult.component;
    component.computeCanonicalNames();
    // Initialize DDC.
    var moduleName = p.basenameWithoutExtension(output.toFilePath());

    var classHierarchy = compilerResult.classHierarchy;
    var compilerOptions = Options(
      replCompile: true,
      moduleName: moduleName,
      experiments: experiments,
      emitDebugMetadata: true,
      canaryFeatures: setup.canaryFeatures,
      enableAsserts: setup.enableAsserts,
      moduleFormats: [setup.moduleFormat],
    );
    var coreTypes = compilerResult.coreTypes;

    final importToSummary = Map<Library, Component>.identity();
    final summaryToModule = Map<Component, String>.identity();
    for (var lib in component.libraries) {
      importToSummary[lib] = component;
    }
    summaryToModule[component] = moduleName;

    var kernel2jsCompiler = compilerOptions.emitLibraryBundle
        ? LibraryBundleCompiler(component, classHierarchy, compilerOptions,
            importToSummary, summaryToModule, coreTypes: coreTypes)
        : ProgramCompiler(component, classHierarchy, compilerOptions,
            importToSummary, summaryToModule,
            coreTypes: coreTypes);
    var module = kernel2jsCompiler.emitModule(component);

    var moduleFormat = compilerOptions.emitLibraryBundle
        ? ModuleFormat.ddcLibraryBundle
        : setup.moduleFormat;

    // Perform a full compile, writing the compiled JS + sourcemap.
    var code = jsProgramToCode(
      module,
      moduleFormat,
      inlineSourceMap: compilerOptions.inlineSourceMap,
      buildSourceMap: compilerOptions.sourceMap,
      emitDebugMetadata: compilerOptions.emitDebugMetadata,
      emitDebugSymbols: compilerOptions.emitDebugSymbols,
      jsUrl: '$output',
      mapUrl: '$output.map',
      compiler: kernel2jsCompiler,
      component: component,
    );
    var codeBytes = utf8.encode(code.code);
    var sourceMapBytes = utf8.encode(json.encode(code.sourceMap));

    File(output.toFilePath()).writeAsBytesSync(codeBytes);
    File('${output.toFilePath()}.map').writeAsBytesSync(sourceMapBytes);

    // Save the expression compiler for future compilation.
    var compiler = ExpressionCompiler(
      setup.options,
      moduleFormat,
      setup.errors,
      frontend,
      kernel2jsCompiler,
      component,
    );

    if (setup.errors.isNotEmpty) {
      throw Exception('Compilation failed with: ${setup.errors}');
    }
    setup.diagnosticMessages.clear();
    setup.errors.clear();

    var sourceMap = source_maps.SingleMapping.fromJson(code.sourceMap!);
    return TestExpressionCompiler._(
        setup, component, compiler, code.metadata, sourceMap);
  }

  // Line and column are 1-based.
  Future<TestCompilationResult> compileExpression(
      {required Uri libraryUri,
      Uri? scriptUri,
      required int line,
      required int column,
      required Map<String, String> scope,
      required String expression}) async {
    // clear previous errors
    setup.errors.clear();

    // At this time, no metadata is stored for the Dart SDK. This is one of the
    // reasons debugging and expression evaluation support is so limited within
    // the SDK.  When requesting evaluation of library level expressions, we can
    // ignore the lack of metadata and simply use the URI directly.
    String importUri;
    if (libraryUri.isScheme('dart')) {
      importUri = libraryUri.toString();
    } else {
      var libraryMetadata = metadataForLibraryUri(libraryUri);
      importUri = libraryMetadata.importUri;
    }
    var jsExpression = await compiler.compileExpressionToJs(
        importUri, scriptUri?.toString(), line, column, scope, expression);
    if (setup.errors.isNotEmpty) {
      jsExpression = setup.errors.toString().replaceAll(
          RegExp(
              r'org-dartlang-debug:synthetic_debug_expression:[0-9]*:[0-9]*:'),
          '');

      return TestCompilationResult(jsExpression, false);
    }

    return TestCompilationResult(jsExpression, true);
  }

  LibraryMetadata metadataForLibraryUri(Uri libraryUri) =>
      metadata!.libraries.entries
          .firstWhere((entry) => entry.value.fileUri == '$libraryUri')
          .value;
}
