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

// ignore_for_file: implementation_imports

import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:args/args.dart';
import 'package:dev_compiler/dev_compiler.dart';
import 'package:dev_compiler/src/command/command.dart';
import 'package:dev_compiler/src/kernel/hot_reload_delta_inspector.dart';
import 'package:dev_compiler/src/js_ast/nodes.dart';
import 'package:front_end/src/api_unstable/vm.dart' show FileSystem;
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
import 'package:package_config/package_config.dart';
import 'package:path/path.dart' as p;

import 'strong_components.dart';

/// Produce a special bundle format for compiled JavaScript.
///
/// The bundle format consists of two files: One containing all produced
/// JavaScript library bundles concatenated together, and a second containing
/// the byte offsets by the synthesized library bundle name for each JavaScript
/// library bundle in JSON format. The library bundle name is based off of a
/// library URI from the associated component.
///
/// The format is analogous to the dill and .incremental.dill in that during
/// an incremental build, a different file is written for each which contains
/// only the updated libraries.
class IncrementalJavaScriptBundler {
  IncrementalJavaScriptBundler(
    this._fileSystem,
    this._loadedLibraries,
    this._fileSystemScheme, {
    this.useDebuggerModuleNames = false,
    this.emitDebugMetadata = false,
    this.emitDebugSymbols = false,
    this.useStronglyConnectedComponents = true,
    this.canaryFeatures = false,
    String? moduleFormat,
    this.extraDdcOptions = const [],
  }) : _moduleFormat = parseModuleFormat(moduleFormat ?? 'amd');

  final bool useDebuggerModuleNames;
  final bool emitDebugMetadata;
  final bool emitDebugSymbols;
  final bool useStronglyConnectedComponents;
  final ModuleFormat _moduleFormat;
  final List<String> extraDdcOptions;
  final bool canaryFeatures;
  final FileSystem? _fileSystem;
  final Set<Library> _loadedLibraries;
  final Map<Uri, Component> _uriToComponent = <Uri, Component>{};
  final _libraryToSummary = new Map<Library, Component>.identity();
  final _summaryToLibraryBundleName = new Map<Component, String>.identity();
  final Map<Uri, String> _summaryToLibraryBundleJSPath = <Uri, String>{};
  final String _fileSystemScheme;
  final HotReloadDeltaInspector _deltaInspector = new HotReloadDeltaInspector();

  late HotReloadLibraryMetadataRepository _libraryMetadataRepository;
  late Component _lastFullComponent;
  late Component _currentComponent;
  late StrongComponents _strongComponents;

  /// Initialize the incremental bundler from a full component.
  Future<void> initialize(
      Component fullComponent, Uri mainUri, PackageConfig packageConfig) async {
    _lastFullComponent = fullComponent;
    _currentComponent = fullComponent;
    // Initialize fresh hot reload metadata for this compile and throw out all
    // information collected from any previous series of hot reloads compiles.
    _libraryMetadataRepository = new HotReloadLibraryMetadataRepository();
    Iterable<Uri> initialLibraryUris;
    if (useStronglyConnectedComponents) {
      _strongComponents = new StrongComponents(
        fullComponent,
        _loadedLibraries,
        mainUri,
        _fileSystem,
      );
      await _strongComponents.computeLibraryBundles();
      initialLibraryUris =
          _strongComponents.libraryBundleImportToLibraries.keys;
    } else {
      initialLibraryUris =
          fullComponent.libraries.map((library) => library.importUri);
    }
    _updateSummaries(initialLibraryUris, packageConfig);
  }

  /// Update the incremental bundler from a partial component and the last full
  /// component.
  Future<void> invalidate(Component partialComponent,
      Component lastFullComponent, Uri mainUri, PackageConfig packageConfig,
      {required bool recompileRestart}) async {
    if (canaryFeatures &&
        _moduleFormat == ModuleFormat.ddc &&
        !recompileRestart) {
      // Attach the global metadata to the last full component. The delta
      // inspector will add to it while comparing the two components.
      lastFullComponent.addMetadataRepository(_libraryMetadataRepository);
      // Find any potential hot reload rejections before updating the strongly
      // connected component graph.
      final List<String> errors = _deltaInspector.compareGenerations(
          lastFullComponent, partialComponent);
      if (errors.isNotEmpty) {
        throw new Exception(errors.join('/n') +
            '\nHot reload rejected due to unsupported changes. '
                'Try performing a hot restart instead.');
      }
    }
    _currentComponent = partialComponent;
    _updateFullComponent(lastFullComponent, partialComponent);
    Iterable<Uri> invalidatedLibraryUris;

    if (useStronglyConnectedComponents) {
      _strongComponents = new StrongComponents(
        _lastFullComponent,
        _loadedLibraries,
        mainUri,
        _fileSystem,
      );
      await _strongComponents.computeLibraryBundles(<Uri, Library>{
        for (Library library in partialComponent.libraries)
          library.importUri: library,
      });
      invalidatedLibraryUris = <Uri>{
        for (Library library in partialComponent.libraries)
          _strongComponents
              .libraryImportToLibraryBundleImport[library.importUri]!,
      };
    } else {
      invalidatedLibraryUris =
          partialComponent.libraries.map((library) => library.importUri);
    }
    _updateSummaries(invalidatedLibraryUris, packageConfig);
  }

  void _updateFullComponent(Component lastKnownGood, Component candidate) {
    Map<Uri, Library> combined = <Uri, Library>{};
    Map<Uri, Source> uriToSource = <Uri, Source>{};
    for (Library library in lastKnownGood.libraries) {
      combined[library.importUri] = library;
    }
    for (Library library in candidate.libraries) {
      combined[library.importUri] = library;
    }
    uriToSource.addAll(lastKnownGood.uriToSource);
    uriToSource.addAll(candidate.uriToSource);

    _lastFullComponent = new Component(
      libraries: combined.values.toList(),
      uriToSource: uriToSource,
    )..setMainMethodAndMode(candidate.mainMethod?.reference, true);
    for (final MetadataRepository repo in candidate.metadata.values) {
      _lastFullComponent.addMetadataRepository(repo);
    }
  }

  /// Update the summaries using the [libraryBundleImports].
  void _updateSummaries(
      Iterable<Uri> libraryBundleImports, PackageConfig packageConfig) {
    final Map<Uri, Library> libraryUriToLibrary = {
      for (Library library in _lastFullComponent.libraries)
        library.importUri: library,
    };
    for (Uri uri in libraryBundleImports) {
      final List<Library> libraries = useStronglyConnectedComponents
          ? _strongComponents.libraryBundleImportToLibraries[uri]!.toList()
          : [libraryUriToLibrary[uri]!];
      final Component summaryComponent = new Component(
        libraries: libraries,
        nameRoot: _lastFullComponent.root,
        uriToSource: _lastFullComponent.uriToSource,
      );
      summaryComponent.setMainMethodAndMode(null, false);

      String baseName = urlForComponentUri(uri, packageConfig);
      _summaryToLibraryBundleJSPath[uri] = '$baseName.lib.js';
      // Library bundle loaders loads bundles by bundle names, not paths
      String libraryBundleName = makeLibraryBundleName(baseName);

      _uriToComponent[uri] = summaryComponent;

      List<Component> oldSummaries = [];
      for (Component summary in _summaryToLibraryBundleName.keys) {
        if (_summaryToLibraryBundleName[summary] == libraryBundleName) {
          oldSummaries.add(summary);
        }
      }
      for (Component summary in oldSummaries) {
        _summaryToLibraryBundleName.remove(summary);
      }
      _libraryToSummary
          .removeWhere((key, value) => oldSummaries.contains(value));

      for (Library library in summaryComponent.libraries) {
        assert(!_libraryToSummary.containsKey(library));
        _libraryToSummary[library] = summaryComponent;
        _summaryToLibraryBundleName[summaryComponent] = libraryBundleName;
      }
    }
  }

  /// Reports if [option] in [extraDdcOptions] was overridden or extended
  /// to [newValue] before being passed to DDC.
  void _checkOverriddenExtraDdcOption(
      ArgResults extraDdcOptionsResults, String option, dynamic newValue) {
    if (extraDdcOptionsResults.wasParsed(option)) {
      if (newValue is List) {
        if (listEquals(extraDdcOptionsResults[option], newValue)) return;
      } else if (newValue == extraDdcOptionsResults[option]) {
        return;
      }
      print("Warning: DDC option '$option' was overridden to '$newValue'.");
    }
  }

  /// Compile each component into a single JavaScript library bundle.
  Future<Map<String, Compiler>> compile(
    ClassHierarchy classHierarchy,
    CoreTypes coreTypes,
    PackageConfig packageConfig,
    IOSink codeSink,
    IOSink manifestSink,
    IOSink sourceMapsSink,
    IOSink? metadataSink,
    IOSink? symbolsSink,
  ) async {
    int codeOffset = 0;
    int sourceMapOffset = 0;
    int metadataOffset = 0;
    int symbolsOffset = 0;
    final Map<String, Map<String, List<int>>> manifest = {};
    final Map<Uri, Compiler> visited = {};
    final Map<String, Compiler> kernel2JsCompilers = {};

    for (Library library in _currentComponent.libraries) {
      if (_loadedLibraries.contains(library) ||
          library.importUri.isScheme('dart')) {
        continue;
      }

      final Uri libraryOrLibraryBundleImportUri = useStronglyConnectedComponents
          ? _strongComponents
              .libraryImportToLibraryBundleImport[library.importUri]!
          : library.importUri;
      if (visited.containsKey(libraryOrLibraryBundleImportUri)) {
        kernel2JsCompilers[library.importUri.toString()] =
            visited[libraryOrLibraryBundleImportUri]!;
        continue;
      }

      final Component summaryComponent =
          _uriToComponent[libraryOrLibraryBundleImportUri]!;

      final String componentUrl =
          urlForComponentUri(libraryOrLibraryBundleImportUri, packageConfig);
      // Library bundle name to use in trackLibraries. Use the full path for
      // tracking if library bundle uri is not a package uri.
      final String libraryBundleName = makeLibraryBundleName(componentUrl);
      // Issue a warning when provided [extraDdcOptions] were overridden.
      final ArgResults extraDdcOptionsResults =
          Options.nonSdkArgParser().parse(extraDdcOptions);
      _checkOverriddenExtraDdcOption(
          extraDdcOptionsResults, 'source-map', true);
      _checkOverriddenExtraDdcOption(
          extraDdcOptionsResults, 'summarize', false);
      _checkOverriddenExtraDdcOption(extraDdcOptionsResults,
          'experimental-emit-debug-metadata', emitDebugMetadata);
      _checkOverriddenExtraDdcOption(
          extraDdcOptionsResults, 'emit-debug-symbols', emitDebugSymbols);
      _checkOverriddenExtraDdcOption(
          extraDdcOptionsResults, 'canary', canaryFeatures);
      _checkOverriddenExtraDdcOption(
          extraDdcOptionsResults, 'module-name', libraryBundleName);
      _checkOverriddenExtraDdcOption(
          extraDdcOptionsResults, 'modules', [libraryBundleName]);
      // Apply existing Frontend Server flags over options selected in
      // [extraDdcOptions].
      final List<String> ddcArgs = [
        ...extraDdcOptions,
        '--source-map',
        '--no-summarize',
        emitDebugMetadata
            ? '--experimental-emit-debug-metadata'
            : '--no-experimental-emit-debug-metadata',
        emitDebugSymbols ? '--emit-debug-symbols' : '--no-emit-debug-symbols',
        canaryFeatures ? '--canary' : '--no-canary',
        '--module-name=$libraryBundleName',
        '--modules=${_moduleFormat.flagName}',
      ];
      final Options ddcOptions =
          new Options.fromArguments(Options.nonSdkArgParser().parse(ddcArgs));
      Compiler compiler;
      if (ddcOptions.emitLibraryBundle) {
        compiler = new LibraryBundleCompiler(
          _currentComponent,
          classHierarchy,
          ddcOptions,
          _libraryToSummary,
          _summaryToLibraryBundleName,
          coreTypes: coreTypes,
        );
        // Attach all the hot reload metadata collected so far to the component
        // that is about to be compiled.
        summaryComponent.addMetadataRepository(_libraryMetadataRepository);
      } else {
        compiler = new ProgramCompiler(
          _currentComponent,
          classHierarchy,
          ddcOptions,
          _libraryToSummary,
          _summaryToLibraryBundleName,
          coreTypes: coreTypes,
        );
      }
      final Program jsBundle = compiler.emitModule(summaryComponent);

      // Save program compiler to reuse for expression evaluation.
      kernel2JsCompilers[library.importUri.toString()] = compiler;
      visited[libraryOrLibraryBundleImportUri] = compiler;

      String? sourceMapBase;
      if (libraryOrLibraryBundleImportUri.isScheme('package')) {
        // Source locations come through as absolute file uris. In order to
        // make relative paths in the source map we get the absolute uri for
        // the library bundle and make them relative to that.
        sourceMapBase = p.dirname(
            (packageConfig.resolve(libraryOrLibraryBundleImportUri))!.path);
      }

      final JSCode code = jsProgramToCode(
        jsBundle,
        ddcOptions.emitLibraryBundle
            ? ModuleFormat.ddcLibraryBundle
            : _moduleFormat,
        inlineSourceMap: true,
        buildSourceMap: true,
        emitDebugMetadata: emitDebugMetadata,
        emitDebugSymbols: emitDebugSymbols,
        jsUrl: '$componentUrl.lib.js',
        mapUrl: '$componentUrl.lib.js.map',
        sourceMapBase: sourceMapBase,
        customScheme: _fileSystemScheme,
        compiler: compiler,
        component: summaryComponent,
        // Only pass a package configuration if the serve time package paths are
        // not being enforced by the `useDebuggerModuleNames` option.
        packageConfig: useDebuggerModuleNames ? null : packageConfig,
      );
      final Uint8List codeBytes = utf8.encode(code.code);
      final Uint8List sourceMapBytes = utf8.encode(json.encode(code.sourceMap));
      final Uint8List? metadataBytes =
          emitDebugMetadata ? utf8.encode(json.encode(code.metadata)) : null;
      final Uint8List? symbolsBytes =
          emitDebugSymbols ? utf8.encode(json.encode(code.symbols)) : null;

      codeSink.add(codeBytes);
      sourceMapsSink.add(sourceMapBytes);
      if (emitDebugMetadata) {
        metadataSink!.add(metadataBytes!);
      }
      if (emitDebugSymbols) {
        symbolsSink!.add(symbolsBytes!);
      }
      final String libraryBundleJSPath =
          _summaryToLibraryBundleJSPath[libraryOrLibraryBundleImportUri]!;
      manifest[libraryBundleJSPath] = {
        'code': <int>[codeOffset, codeOffset += codeBytes.length],
        'sourcemap': <int>[
          sourceMapOffset,
          sourceMapOffset += sourceMapBytes.length
        ],
        if (emitDebugMetadata)
          'metadata': <int>[
            metadataOffset,
            metadataOffset += metadataBytes!.length
          ],
        if (emitDebugSymbols)
          'symbols': <int>[
            symbolsOffset,
            symbolsOffset += symbolsBytes!.length,
          ],
      };
    }
    manifestSink.add(utf8.encode(json.encode(manifest)));

    return kernel2JsCompilers;
  }

  /// Library bundle name used in the browser to load library bundles.
  ///
  /// Library bundle names are used to load library bundles using library bundle
  /// path maps in RequireJS, which treats names with leading '/' or '.js'
  /// extensions specially, and tries to load them without mapping. Skip the
  /// leading '/' to always load library bundles via library bundle path maps.
  String makeLibraryBundleName(String name) {
    return name.startsWith('/') ? name.substring(1) : name;
  }

  /// Create component url.
  ///
  /// Used as a server path in the browser for the library bundle created from
  /// the component.
  String urlForComponentUri(Uri componentUri, PackageConfig packageConfig) {
    if (!componentUri.isScheme('package')) {
      return componentUri.path;
    }
    if (!useDebuggerModuleNames) {
      return '/packages/${componentUri.path}';
    }
    // Match relative directory structure of server paths to the
    // actual directory structure, so the sourcemaps relative paths
    // can be resolved by the browser.
    final Uri resolvedUri = packageConfig.resolve(componentUri)!;
    final Package package = packageConfig.packageOf(resolvedUri)!;
    final Uri root = package.root;
    final String relativeRoot =
        root.pathSegments.lastWhere((segment) => segment.isNotEmpty);
    final String relativeUrl = resolvedUri.toString().replaceFirst('$root', '');

    // Relative component url (used as server path in the browser):
    // `packages/<package directory>/<path to file.dart>`
    return 'packages/$relativeRoot/$relativeUrl';
  }
}
