// 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:dev_compiler/dev_compiler.dart';
import 'package:dev_compiler/src/command/command.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 modules concatenated together, and a second containing the byte
/// offsets by module name for each JavaScript module in JSON format.
///
/// 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.canaryFeatures = false,
    String? moduleFormat,
  }) : _moduleFormat = parseModuleFormat(moduleFormat ?? 'amd');

  final bool useDebuggerModuleNames;
  final bool emitDebugMetadata;
  final bool emitDebugSymbols;
  final ModuleFormat _moduleFormat;
  final bool canaryFeatures;
  final FileSystem? _fileSystem;
  final Set<Library> _loadedLibraries;
  final Map<Uri, Component> _uriToComponent = <Uri, Component>{};
  final _importToSummary = new Map<Library, Component>.identity();
  final _summaryToModule = new Map<Component, String>.identity();
  final Map<Uri, String> _moduleImportForSummary = <Uri, String>{};
  final Map<Uri, String> _moduleImportNameForSummary = <Uri, String>{};
  final String _fileSystemScheme;

  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;
    _strongComponents = new StrongComponents(
      fullComponent,
      _loadedLibraries,
      mainUri,
      _fileSystem,
    );
    await _strongComponents.computeModules();
    _updateSummaries(_strongComponents.modules.keys, 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) async {
    _currentComponent = partialComponent;
    _updateFullComponent(lastFullComponent, partialComponent);
    _strongComponents = new StrongComponents(
      _lastFullComponent,
      _loadedLibraries,
      mainUri,
      _fileSystem,
    );

    await _strongComponents.computeModules(<Uri, Library>{
      for (Library library in partialComponent.libraries)
        library.importUri: library,
    });
    Set<Uri> invalidated = <Uri>{
      for (Library library in partialComponent.libraries)
        _strongComponents.moduleAssignment[library.importUri]!,
    };
    _updateSummaries(invalidated, 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, candidate.mode);
    for (final MetadataRepository repo in candidate.metadata.values) {
      _lastFullComponent.addMetadataRepository(repo);
    }
  }

  /// Update the summaries [moduleKeys].
  void _updateSummaries(Iterable<Uri> moduleKeys, PackageConfig packageConfig) {
    for (Uri uri in moduleKeys) {
      final List<Library> libraries = _strongComponents.modules[uri]!.toList();
      final Component summaryComponent = new Component(
        libraries: libraries,
        nameRoot: _lastFullComponent.root,
        uriToSource: _lastFullComponent.uriToSource,
      );
      summaryComponent.setMainMethodAndMode(
          null, false, _currentComponent.mode);

      String baseName = urlForComponentUri(uri, packageConfig);
      _moduleImportForSummary[uri] = '$baseName.lib.js';
      _moduleImportNameForSummary[uri] = makeModuleName(baseName);

      _uriToComponent[uri] = summaryComponent;
      // module loaders loads modules by modules names, not paths
      String moduleImport = _moduleImportNameForSummary[uri]!;

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

      for (Library library in summaryComponent.libraries) {
        assert(!_importToSummary.containsKey(library));
        _importToSummary[library] = summaryComponent;
        _summaryToModule[summaryComponent] = moduleImport;
      }
    }
  }

  /// Compile each component into a single JavaScript module.
  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 Set<Uri> visited = {};
    final Map<String, Compiler> kernel2JsCompilers = {};

    for (Library library in _currentComponent.libraries) {
      if (_loadedLibraries.contains(library) ||
          library.importUri.isScheme('dart')) {
        continue;
      }
      final Uri moduleUri =
          _strongComponents.moduleAssignment[library.importUri]!;
      if (visited.contains(moduleUri)) {
        continue;
      }
      visited.add(moduleUri);

      final Component summaryComponent = _uriToComponent[moduleUri]!;

      // module name to use in trackLibraries
      // use full path for tracking if module uri is not a package uri.
      final String moduleUrl = urlForComponentUri(moduleUri, packageConfig);
      final String moduleName = makeModuleName(moduleUrl);
      final Options ddcOptions = new Options(
        sourceMap: true,
        summarizeApi: false,
        emitDebugMetadata: emitDebugMetadata,
        emitDebugSymbols: emitDebugSymbols,
        moduleName: moduleName,
        soundNullSafety: true,
        canaryFeatures: canaryFeatures,
        moduleFormats: [_moduleFormat],
      );
      Compiler compiler = ddcOptions.emitLibraryBundle
          ? new LibraryBundleCompiler(
              _currentComponent,
              classHierarchy,
              ddcOptions,
              _importToSummary,
              _summaryToModule,
              coreTypes: coreTypes,
            )
          : new ProgramCompiler(
              _currentComponent,
              classHierarchy,
              ddcOptions,
              _importToSummary,
              _summaryToModule,
              coreTypes: coreTypes,
            );

      final Program jsModule = compiler.emitModule(summaryComponent);

      // Save program compiler to reuse for expression evaluation.
      kernel2JsCompilers[moduleName] = compiler;

      String? sourceMapBase;
      if (moduleUri.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 module and make them relative to that.
        sourceMapBase = p.dirname((packageConfig.resolve(moduleUri))!.path);
      }

      final JSCode code = jsProgramToCode(
        jsModule,
        ddcOptions.emitLibraryBundle
            ? ModuleFormat.ddcLibraryBundle
            : _moduleFormat,
        inlineSourceMap: true,
        buildSourceMap: true,
        emitDebugMetadata: emitDebugMetadata,
        emitDebugSymbols: emitDebugSymbols,
        jsUrl: '$moduleUrl.lib.js',
        mapUrl: '$moduleUrl.lib.js.map',
        sourceMapBase: sourceMapBase,
        customScheme: _fileSystemScheme,
        compiler: compiler,
        component: summaryComponent,
      );
      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 moduleKey = _moduleImportForSummary[moduleUri]!;
      manifest[moduleKey] = {
        '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;
  }

  /// Module name used in the browser to load modules.
  ///
  /// Module names are used to load modules using module
  /// paths 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 modules via module
  /// path maps.
  String makeModuleName(String name) {
    return name.startsWith('/') ? name.substring(1) : name;
  }

  /// Create component url.
  ///
  /// Used as a server path in the browser for the module 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';
  }
}
