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

library;

// ignore: implementation_imports
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
import 'package:kernel/ast.dart' show Location;

import '../../compiler_api.dart'
    as api
    show CompilerOutput, OutputSink, OutputType;
import '../util/output_util.dart';
import '../util/util.dart';
import 'code_output.dart' show SourceLocationsProvider, SourceLocations;
import 'location_provider.dart';
import 'source_information.dart' show FrameEntry, SourceLocation;

class SourceMapBuilder {
  final String version;
  final StringSink outputSink;

  /// The URI of the source map file.
  final Uri? sourceMapUri;

  /// The URI of the target language file.
  final Uri? targetFileUri;

  final LocationProvider locationProvider;
  final List<SourceMapEntry> entries = [];

  /// Extension used to deobfuscate minified names in error messages.
  final Map<String, String> minifiedGlobalNames;
  final Map<String, String> minifiedInstanceNames;

  /// Contains mapped source locations including inlined frame mappings.
  final SourceLocations sourceLocations;

  SourceMapBuilder(
    this.version,
    this.sourceMapUri,
    this.targetFileUri,
    this.locationProvider,
    this.minifiedGlobalNames,
    this.minifiedInstanceNames,
    this.sourceLocations,
    this.outputSink,
  );

  void addMapping(int targetOffset, SourceLocation sourceLocation) {
    entries.add(SourceMapEntry(sourceLocation, targetOffset));
  }

  void printStringListOn(Iterable<String> strings) {
    bool first = true;
    outputSink.write('[');
    for (String string in strings) {
      if (!first) outputSink.write(',');
      outputSink.write('"');
      writeJsonEscapedCharsOn(string, outputSink);
      outputSink.write('"');
      first = false;
    }
    outputSink.write(']');
  }

  void build() {
    LineColumnMap<SourceMapEntry> lineColumnMap = LineColumnMap();
    for (var sourceMapEntry in entries) {
      Location kernelLocation = locationProvider.getLocation(
        sourceMapEntry.targetOffset,
      );
      int line = kernelLocation.line - 1;
      int column = kernelLocation.column - 1;
      lineColumnMap.add(line, column, sourceMapEntry);
    }

    _build(lineColumnMap);
  }

  void _build(LineColumnMap<SourceMapEntry> lineColumnMap) {
    IndexMap<Uri> uriMap = IndexMap<Uri>();
    IndexMap<String> nameMap = IndexMap<String>();

    void registerLocation(SourceLocation? sourceLocation) {
      if (sourceLocation != null) {
        if (sourceLocation.sourceUri != null) {
          uriMap.register(sourceLocation.sourceUri!);
          if (sourceLocation.sourceName != null) {
            nameMap.register(sourceLocation.sourceName!);
          }
        }
      }
    }

    lineColumnMap.forEachElement((SourceMapEntry entry) {
      registerLocation(entry.sourceLocation);
    });

    (List.of(minifiedGlobalNames.values)..sort()).forEach(nameMap.register);
    (List.of(minifiedInstanceNames.values)..sort()).forEach(nameMap.register);

    final inlinedNames = <String>[];
    sourceLocations.forEachFrameMarker((_, frame) {
      registerLocation(frame.pushLocation);
      if (frame.inlinedMethodName != null) {
        inlinedNames.add(frame.inlinedMethodName!);
      }
    });
    (inlinedNames..sort()).forEach(nameMap.register);

    outputSink.write('{\n');
    outputSink.write('  "version": 3,\n');
    outputSink.write('  "engine": "$version",\n');
    if (sourceMapUri != null && targetFileUri != null) {
      outputSink.write(
        '  "file": '
        '"${fe.relativizeUri(sourceMapUri!, targetFileUri!, false)}",\n',
      );
    }
    outputSink.write('  "sourceRoot": "",\n');
    outputSink.write('  "sources": ');
    Iterable<String> relativeSourceUriList = const <String>[];
    if (sourceMapUri != null) {
      relativeSourceUriList = uriMap.elements.map(
        (u) => fe.relativizeUri(sourceMapUri!, u, false),
      );
    }
    printStringListOn(relativeSourceUriList);
    outputSink.write(',\n');
    outputSink.write('  "names": ');
    printStringListOn(nameMap.elements);
    outputSink.write(',\n');
    outputSink.write('  "mappings": "');
    writeEntries(lineColumnMap, uriMap, nameMap);
    outputSink.write('",\n');
    outputSink.write('  "x_org_dartlang_dart2js": {\n');
    outputSink.write('    "minified_names": {\n');
    outputSink.write('      "global": ');
    writeMinifiedNames(minifiedGlobalNames, nameMap);
    outputSink.write(',\n');
    outputSink.write('      "instance": ');
    writeMinifiedNames(minifiedInstanceNames, nameMap);
    outputSink.write('\n    },\n');
    outputSink.write('    "frames": ');
    writeFrames(uriMap, nameMap);
    outputSink.write('\n  }\n}\n');
  }

  void writeEntries(
    LineColumnMap<SourceMapEntry> entries,
    IndexMap<Uri> uriMap,
    IndexMap<String> nameMap,
  ) {
    SourceLocation? previousSourceLocation;
    int previousTargetLine = 0;
    DeltaEncoder targetColumnEncoder = DeltaEncoder();
    bool firstEntryInLine = true;
    DeltaEncoder sourceUriIndexEncoder = DeltaEncoder();
    DeltaEncoder sourceLineEncoder = DeltaEncoder();
    DeltaEncoder sourceColumnEncoder = DeltaEncoder();
    DeltaEncoder sourceNameIndexEncoder = DeltaEncoder();

    entries.forEach((int targetLine, int targetColumn, SourceMapEntry entry) {
      SourceLocation sourceLocation = entry.sourceLocation;
      if (sourceLocation == previousSourceLocation) {
        return;
      }

      if (targetLine > previousTargetLine) {
        for (int i = previousTargetLine; i < targetLine; ++i) {
          outputSink.write(';');
        }
        previousTargetLine = targetLine;
        previousSourceLocation = null;
        targetColumnEncoder.reset();
        firstEntryInLine = true;
      }

      if (!firstEntryInLine) {
        outputSink.write(',');
      }
      firstEntryInLine = false;

      targetColumnEncoder.encode(outputSink, targetColumn);

      Uri? sourceUri = sourceLocation.sourceUri;
      if (sourceUri != null) {
        sourceUriIndexEncoder.encode(outputSink, uriMap[sourceUri]!);
        sourceLineEncoder.encode(outputSink, sourceLocation.line - 1);
        sourceColumnEncoder.encode(outputSink, sourceLocation.column - 1);
      }

      String? sourceName = sourceLocation.sourceName;
      if (sourceName != null) {
        sourceNameIndexEncoder.encode(outputSink, nameMap[sourceName]!);
      }

      previousSourceLocation = sourceLocation;
    });
  }

  void writeMinifiedNames(
    Map<String, String> minifiedNames,
    IndexMap<String> nameMap,
  ) {
    bool first = true;
    outputSink.write('"');
    for (final minifiedName in List.of(minifiedNames.keys)..sort()) {
      final name = minifiedNames[minifiedName]!;
      if (!first) outputSink.write(',');
      // minifiedNames are valid JS identifiers so they don't need to be escaped
      outputSink.write(minifiedName);
      outputSink.write(',');
      outputSink.write(nameMap[name]);
      first = false;
    }
    outputSink.write('"');
  }

  void writeFrames(IndexMap<Uri> uriMap, IndexMap<String> nameMap) {
    var offsetEncoder = DeltaEncoder();
    var uriEncoder = DeltaEncoder();
    var lineEncoder = DeltaEncoder();
    var columnEncoder = DeltaEncoder();
    var nameEncoder = DeltaEncoder();
    outputSink.write('"');
    sourceLocations.forEachFrameMarker((int offset, FrameEntry entry) {
      offsetEncoder.encode(outputSink, offset);
      if (entry.isPush) {
        SourceLocation location = entry.pushLocation!;
        uriEncoder.encode(outputSink, uriMap[location.sourceUri!]!);
        lineEncoder.encode(outputSink, location.line - 1);
        columnEncoder.encode(outputSink, location.column - 1);
        nameEncoder.encode(outputSink, nameMap[entry.inlinedMethodName!]!);
      } else {
        // ; and , are not used by VLQ so we can distinguish them in the
        // encoding, this is the same reason they are used in the mappings
        // field.
        outputSink.write(entry.isEmptyPop ? ";" : ",");
      }
    });
    outputSink.write('"');
  }

  /// Returns the source map tag to put at the end a .js file in [fileUri] to
  /// make it point to the source map file in [sourceMapUri].
  static String generateSourceMapTag(Uri? sourceMapUri, Uri? fileUri) {
    if (sourceMapUri != null && fileUri != null) {
      String sourceMapFileName = fe.relativizeUri(fileUri, sourceMapUri, false);
      return '''

//# sourceMappingURL=$sourceMapFileName
''';
    }
    return '';
  }

  /// Generates source map files for all [SourceLocations] in
  /// [sourceLocationsProvider] for the .js code in [locationProvider]
  /// [sourceMapUri] is used to relativizes the URIs of the referenced source
  /// files and the target [fileUri]. [name] and [outputProvider] are used to
  /// create the [api.OutputSink] for the source map text.
  static void outputSourceMap(
    SourceLocationsProvider sourceLocationsProvider,
    LocationProvider locationProvider,
    Map<String, String> minifiedGlobalNames,
    Map<String, String> minifiedInstanceNames,
    String name,
    Uri? sourceMapUri,
    Uri? fileUri,
    api.CompilerOutput compilerOutput,
  ) {
    // Create a source file for the compilation output. This allows using
    // [:getLine:] to transform offsets to line numbers in [SourceMapBuilder].
    int index = 0;
    for (var sourceLocations in sourceLocationsProvider.sourceLocations) {
      String extension = 'js.map';
      if (index > 0) {
        if (name == '') {
          name = fileUri != null ? fileUri.pathSegments.last : 'out.js';
          extension = 'map.${sourceLocations.name}';
        } else {
          extension = 'js.map.${sourceLocations.name}';
        }
      }
      final outputSink = BufferedStringSinkWrapper(
        compilerOutput.createOutputSink(
          name,
          extension,
          api.OutputType.sourceMap,
        ),
      );
      SourceMapBuilder sourceMapBuilder = SourceMapBuilder(
        sourceLocations.name,
        sourceMapUri,
        fileUri,
        locationProvider,
        minifiedGlobalNames,
        minifiedInstanceNames,
        sourceLocations,
        outputSink,
      );
      sourceLocations.forEachSourceLocation(sourceMapBuilder.addMapping);
      sourceMapBuilder.build();
      sourceLocations.close();
      outputSink.close();
      index++;
    }
  }
}

/// Encoder for value deltas in VLQ format.
class DeltaEncoder {
  /// The last emitted value of the encoder.
  int _value = 0;

  /// Reset the encoder to its initial state.
  void reset() {
    _value = 0;
  }

  /// Writes the VLQ of delta between [value] and the last emitted value into
  /// [output] and updates the last emitted value of the encoder.
  void encode(StringSink output, int value) {
    _value = encodeVLQ(output, value, _value);
  }

  static const int vlqBaseShift = 5;
  static const int vlqBaseMask = (1 << 5) - 1;
  static const int vlqContinuationBit = 1 << 5;
  static const int vlqContinuationMask = 1 << 5;
  static const String base64Digits =
      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn'
      'opqrstuvwxyz0123456789+/';

  /// Writes the VLQ of delta between [value] and [offset] into [output] and
  /// return [value].
  static int encodeVLQ(StringSink output, int value, int offset) {
    int delta = value - offset;
    int signBit = 0;
    if (delta < 0) {
      signBit = 1;
      delta = -delta;
    }
    delta = (delta << 1) | signBit;
    do {
      int digit = delta & vlqBaseMask;
      delta >>= vlqBaseShift;
      if (delta > 0) {
        digit |= vlqContinuationBit;
      }
      output.write(base64Digits[digit]);
    } while (delta > 0);
    return value;
  }
}

class SourceMapEntry {
  SourceLocation sourceLocation;
  int targetOffset;

  SourceMapEntry(this.sourceLocation, this.targetOffset);
}

/// Map from line/column pairs to lists of [T] elements.
class LineColumnMap<T> {
  final Map<int, Map<int, List<T>>> _map = {};

  /// Returns the list of elements associated with ([line],[column]).
  List<T> _getList(int line, int column) {
    Map<int, List<T>> lineMap = _map[line] ??= {};
    return lineMap[column] ??= [];
  }

  /// Adds [element] to the end of the list of elements associated with
  /// ([line],[column]).
  void add(int line, int column, T element) {
    _getList(line, column).add(element);
  }

  /// Adds [element] to the beginning of the list of elements associated with
  /// ([line],[column]).
  void addFirst(int line, int column, T element) {
    _getList(line, column).insert(0, element);
  }

  /// Calls [f] with the line number for each line with associated elements.
  ///
  /// [f] is called in increasing line order.
  void forEachLine(void Function(int line) f) {
    List<int> lines = _map.keys.toList()..sort();
    lines.forEach(f);
  }

  /// Returns the elements for the first the column in [line] that has
  /// associated elements.
  List<T>? getFirstElementsInLine(int line) {
    Map<int, List<T>>? lineMap = _map[line];
    if (lineMap == null) return null;
    List<int> columns = lineMap.keys.toList()..sort();
    return lineMap[columns.first];
  }

  /// Calls [f] for each column with associated elements in [line].
  ///
  /// [f] is called in increasing column order.
  void forEachColumn(int line, void Function(int column, List<T> elements) f) {
    Map<int, List<T>>? lineMap = _map[line];
    if (lineMap != null) {
      List<int> columns = lineMap.keys.toList()..sort();
      for (var column in columns) {
        f(column, lineMap[column]!);
      }
    }
  }

  /// Calls [f] for each line/column/element triplet in the map.
  ///
  /// [f] is called in increasing line, column, element order.
  void forEach(void Function(int line, int column, T element) f) {
    List<int> lines = _map.keys.toList()..sort();
    for (int line in lines) {
      Map<int, List<T>> lineMap = _map[line]!;
      List<int> columns = lineMap.keys.toList()..sort();
      for (int column in columns) {
        for (var e in lineMap[column]!) {
          f(line, column, e);
        }
      }
    }
  }

  /// Calls [f] for each element associated in the map.
  ///
  /// [f] is called in increasing line, column, element order.
  void forEachElement(void Function(T element) f) {
    forEach((line, column, element) => f(element));
  }
}

/// Map from [T] elements to assigned indices.
class IndexMap<T> {
  Map<T, int> map = {};

  /// Register [element] and returns its index.
  int register(T element) {
    return map.putIfAbsent(element, () => map.length);
  }

  /// Returns the index of [element].
  int? operator [](T element) => map[element];

  /// Returns the indexed elements.
  Iterable<T> get elements => map.keys;
}
