// 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 'location_provider.dart';
import 'code_output.dart' show SourceLocationsProvider, SourceLocations;
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;
}
