// 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/js_ast/nodes.dart';
import 'package:dev_compiler/src/kernel/command.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.soundNullSafety = false,
    this.canaryFeatures = false,
    String? moduleFormat,
  }) : _moduleFormat = parseModuleFormat(moduleFormat ?? 'amd');

  final bool useDebuggerModuleNames;
  final bool emitDebugMetadata;
  final bool emitDebugSymbols;
  final ModuleFormat _moduleFormat;
  final bool soundNullSafety;
  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, ProgramCompiler>> 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, ProgramCompiler> 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);

      ProgramCompiler compiler = new ProgramCompiler(
        _currentComponent,
        classHierarchy,
        new SharedCompilerOptions(
          sourceMap: true,
          summarizeApi: false,
          emitDebugMetadata: emitDebugMetadata,
          emitDebugSymbols: emitDebugSymbols,
          moduleName: moduleName,
          soundNullSafety: soundNullSafety,
          canaryFeatures: canaryFeatures,
        ),
        _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,
        _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';
  }
}
