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

/// Contains the top-level function to parse source maps version 3.
library;

import 'dart:convert';

import 'package:source_span/source_span.dart';

import 'builder.dart' as builder;
import 'src/source_map_span.dart';
import 'src/utils.dart';
import 'src/vlq.dart';

/// Parses a source map directly from a json string.
///
/// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of
/// the source map file itself. If it's passed, any URLs in the source
/// map will be interpreted as relative to this URL when generating spans.
// TODO(sigmund): evaluate whether other maps should have the json parsed, or
// the string represenation.
// TODO(tjblasi): Ignore the first line of [jsonMap] if the JSON safety string
// `)]}'` begins the string representation of the map.
Mapping parse(String jsonMap,
        {Map<String, Map>? otherMaps, /*String|Uri*/ Object? mapUrl}) =>
    parseJson(jsonDecode(jsonMap) as Map, otherMaps: otherMaps, mapUrl: mapUrl);

/// Parses a source map or source map bundle directly from a json string.
///
/// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of
/// the source map file itself. If it's passed, any URLs in the source
/// map will be interpreted as relative to this URL when generating spans.
Mapping parseExtended(String jsonMap,
        {Map<String, Map>? otherMaps, /*String|Uri*/ Object? mapUrl}) =>
    parseJsonExtended(jsonDecode(jsonMap),
        otherMaps: otherMaps, mapUrl: mapUrl);

/// Parses a source map or source map bundle.
///
/// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of
/// the source map file itself. If it's passed, any URLs in the source
/// map will be interpreted as relative to this URL when generating spans.
Mapping parseJsonExtended(/*List|Map*/ Object? json,
    {Map<String, Map>? otherMaps, /*String|Uri*/ Object? mapUrl}) {
  if (json is List) {
    return MappingBundle.fromJson(json, mapUrl: mapUrl);
  }
  return parseJson(json as Map);
}

/// Parses a source map.
///
/// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of
/// the source map file itself. If it's passed, any URLs in the source
/// map will be interpreted as relative to this URL when generating spans.
Mapping parseJson(Map map,
    {Map<String, Map>? otherMaps, /*String|Uri*/ Object? mapUrl}) {
  if (map['version'] != 3) {
    throw ArgumentError('unexpected source map version: ${map["version"]}. '
        'Only version 3 is supported.');
  }

  if (map.containsKey('sections')) {
    if (map.containsKey('mappings') ||
        map.containsKey('sources') ||
        map.containsKey('names')) {
      throw const FormatException('map containing "sections" '
          'cannot contain "mappings", "sources", or "names".');
    }
    return MultiSectionMapping.fromJson(map['sections'] as List, otherMaps,
        mapUrl: mapUrl);
  }
  return SingleMapping.fromJson(map.cast<String, dynamic>(), mapUrl: mapUrl);
}

/// A mapping parsed out of a source map.
abstract class Mapping {
  /// Returns the span associated with [line] and [column].
  ///
  /// [uri] is the optional location of the output file to find the span for
  /// to disambiguate cases where a mapping may have different mappings for
  /// different output files.
  SourceMapSpan? spanFor(int line, int column,
      {Map<String, SourceFile>? files, String? uri});

  /// Returns the span associated with [location].
  SourceMapSpan? spanForLocation(SourceLocation location,
      {Map<String, SourceFile>? files}) {
    return spanFor(location.line, location.column,
        uri: location.sourceUrl?.toString(), files: files);
  }
}

/// A meta-level map containing sections.
class MultiSectionMapping extends Mapping {
  /// For each section, the start line offset.
  final List<int> _lineStart = <int>[];

  /// For each section, the start column offset.
  final List<int> _columnStart = <int>[];

  /// For each section, the actual source map information, which is not adjusted
  /// for offsets.
  final List<Mapping> _maps = <Mapping>[];

  /// Creates a section mapping from json.
  MultiSectionMapping.fromJson(List sections, Map<String, Map>? otherMaps,
      {/*String|Uri*/ Object? mapUrl}) {
    for (var section in sections.cast<Map>()) {
      var offset = section['offset'] as Map?;
      if (offset == null) throw const FormatException('section missing offset');

      var line = offset['line'] as int?;
      if (line == null) throw const FormatException('offset missing line');

      var column = offset['column'] as int?;
      if (column == null) throw const FormatException('offset missing column');

      _lineStart.add(line);
      _columnStart.add(column);

      var url = section['url'] as String?;
      var map = section['map'] as Map?;

      if (url != null && map != null) {
        throw const FormatException(
            "section can't use both url and map entries");
      } else if (url != null) {
        var other = otherMaps?[url];
        if (otherMaps == null || other == null) {
          throw FormatException(
              'section contains refers to $url, but no map was '
              'given for it. Make sure a map is passed in "otherMaps"');
        }
        _maps.add(parseJson(other, otherMaps: otherMaps, mapUrl: url));
      } else if (map != null) {
        _maps.add(parseJson(map, otherMaps: otherMaps, mapUrl: mapUrl));
      } else {
        throw const FormatException('section missing url or map');
      }
    }
    if (_lineStart.isEmpty) {
      throw const FormatException('expected at least one section');
    }
  }

  int _indexFor(int line, int column) {
    for (var i = 0; i < _lineStart.length; i++) {
      if (line < _lineStart[i]) return i - 1;
      if (line == _lineStart[i] && column < _columnStart[i]) return i - 1;
    }
    return _lineStart.length - 1;
  }

  @override
  SourceMapSpan? spanFor(int line, int column,
      {Map<String, SourceFile>? files, String? uri}) {
    // TODO(jacobr): perhaps verify that targetUrl matches the actual uri
    // or at least ends in the same file name.
    var index = _indexFor(line, column);
    return _maps[index].spanFor(
        line - _lineStart[index], column - _columnStart[index],
        files: files);
  }

  @override
  String toString() {
    var buff = StringBuffer('$runtimeType : [');
    for (var i = 0; i < _lineStart.length; i++) {
      buff
        ..write('(')
        ..write(_lineStart[i])
        ..write(',')
        ..write(_columnStart[i])
        ..write(':')
        ..write(_maps[i])
        ..write(')');
    }
    buff.write(']');
    return buff.toString();
  }
}

class MappingBundle extends Mapping {
  final Map<String, SingleMapping> _mappings = {};

  MappingBundle();

  MappingBundle.fromJson(List json, {/*String|Uri*/ Object? mapUrl}) {
    for (var map in json) {
      addMapping(parseJson(map as Map, mapUrl: mapUrl) as SingleMapping);
    }
  }

  void addMapping(SingleMapping mapping) {
    // TODO(jacobr): verify that targetUrl is valid uri instead of a windows
    // path.
    // TODO: Remove type arg https://github.com/dart-lang/sdk/issues/42227
    var targetUrl = ArgumentError.checkNotNull<String>(
        mapping.targetUrl, 'mapping.targetUrl');
    _mappings[targetUrl] = mapping;
  }

  /// Encodes the Mapping mappings as a json map.
  List toJson() => _mappings.values.map((v) => v.toJson()).toList();

  @override
  String toString() {
    var buff = StringBuffer();
    for (var map in _mappings.values) {
      buff.write(map.toString());
    }
    return buff.toString();
  }

  bool containsMapping(String url) => _mappings.containsKey(url);

  @override
  SourceMapSpan? spanFor(int line, int column,
      {Map<String, SourceFile>? files, String? uri}) {
    // TODO: Remove type arg https://github.com/dart-lang/sdk/issues/42227
    uri = ArgumentError.checkNotNull<String>(uri, 'uri');

    // Find the longest suffix of the uri that matches the sourcemap
    // where the suffix starts after a path segment boundary.
    // We consider ":" and "/" as path segment boundaries so that
    // "package:" uris can be handled with minimal special casing. Having a
    // few false positive path segment boundaries is not a significant issue
    // as we prefer the longest matching prefix.
    // Using package:path `path.split` to find path segment boundaries would
    // not generate all of the path segment boundaries we want for "package:"
    // urls as "package:package_name" would be one path segment when we want
    // "package" and "package_name" to be sepearate path segments.

    var onBoundary = true;
    var separatorCodeUnits = ['/'.codeUnitAt(0), ':'.codeUnitAt(0)];
    for (var i = 0; i < uri.length; ++i) {
      if (onBoundary) {
        var candidate = uri.substring(i);
        var candidateMapping = _mappings[candidate];
        if (candidateMapping != null) {
          return candidateMapping.spanFor(line, column,
              files: files, uri: candidate);
        }
      }
      onBoundary = separatorCodeUnits.contains(uri.codeUnitAt(i));
    }

    // Note: when there is no source map for an uri, this behaves like an
    // identity function, returning the requested location as the result.

    // Create a mock offset for the output location. We compute it in terms
    // of the input line and column to minimize the chances that two different
    // line and column locations are mapped to the same offset.
    var offset = line * 1000000 + column;
    var location = SourceLocation(offset,
        line: line, column: column, sourceUrl: Uri.parse(uri));
    return SourceMapSpan(location, location, '');
  }
}

/// A map containing direct source mappings.
class SingleMapping extends Mapping {
  /// Source urls used in the mapping, indexed by id.
  final List<String> urls;

  /// Source names used in the mapping, indexed by id.
  final List<String> names;

  /// The [SourceFile]s to which the entries in [lines] refer.
  ///
  /// This is in the same order as [urls]. If this was constructed using
  /// [SingleMapping.fromEntries], this contains files from any [FileLocation]s
  /// used to build the mapping. If it was parsed from JSON, it contains files
  /// for any sources whose contents were provided via the `"sourcesContent"`
  /// field.
  ///
  /// Files whose contents aren't available are `null`.
  final List<SourceFile?> files;

  /// Entries indicating the beginning of each span.
  final List<TargetLineEntry> lines;

  /// Url of the target file.
  String? targetUrl;

  /// Source root prepended to all entries in [urls].
  String? sourceRoot;

  final Uri? _mapUrl;

  final Map<String, dynamic> extensions;

  SingleMapping._(this.targetUrl, this.files, this.urls, this.names, this.lines)
      : _mapUrl = null,
        extensions = {};

  factory SingleMapping.fromEntries(Iterable<builder.Entry> entries,
      [String? fileUrl]) {
    // The entries needs to be sorted by the target offsets.
    var sourceEntries = entries.toList()..sort();
    var lines = <TargetLineEntry>[];

    // Indices associated with file urls that will be part of the source map. We
    // rely on map order so that `urls.keys[urls[u]] == u`
    var urls = <String, int>{};

    // Indices associated with identifiers that will be part of the source map.
    // We rely on map order so that `names.keys[names[n]] == n`
    var names = <String, int>{};

    /// The file for each URL, indexed by [urls]' values.
    var files = <int, SourceFile>{};

    int? lineNum;
    late List<TargetEntry> targetEntries;
    for (var sourceEntry in sourceEntries) {
      if (lineNum == null || sourceEntry.target.line > lineNum) {
        lineNum = sourceEntry.target.line;
        targetEntries = <TargetEntry>[];
        lines.add(TargetLineEntry(lineNum, targetEntries));
      }

      var sourceUrl = sourceEntry.source.sourceUrl;
      var urlId = urls.putIfAbsent(
          sourceUrl == null ? '' : sourceUrl.toString(), () => urls.length);

      if (sourceEntry.source is FileLocation) {
        files.putIfAbsent(
            urlId, () => (sourceEntry.source as FileLocation).file);
      }

      var sourceEntryIdentifierName = sourceEntry.identifierName;
      var srcNameId = sourceEntryIdentifierName == null
          ? null
          : names.putIfAbsent(sourceEntryIdentifierName, () => names.length);
      targetEntries.add(TargetEntry(sourceEntry.target.column, urlId,
          sourceEntry.source.line, sourceEntry.source.column, srcNameId));
    }
    return SingleMapping._(fileUrl, urls.values.map((i) => files[i]).toList(),
        urls.keys.toList(), names.keys.toList(), lines);
  }

  SingleMapping.fromJson(Map<String, dynamic> map, {Object? mapUrl})
      : targetUrl = map['file'] as String?,
        urls = List<String>.from(map['sources'] as List),
        names = List<String>.from((map['names'] as List?) ?? []),
        files = List.filled((map['sources'] as List).length, null),
        sourceRoot = map['sourceRoot'] as String?,
        lines = <TargetLineEntry>[],
        _mapUrl = mapUrl is String ? Uri.parse(mapUrl) : (mapUrl as Uri?),
        extensions = {} {
    var sourcesContent = map['sourcesContent'] == null
        ? const <String?>[]
        : List<String?>.from(map['sourcesContent'] as List);
    for (var i = 0; i < urls.length && i < sourcesContent.length; i++) {
      var source = sourcesContent[i];
      if (source == null) continue;
      files[i] = SourceFile.fromString(source, url: urls[i]);
    }

    var line = 0;
    var column = 0;
    var srcUrlId = 0;
    var srcLine = 0;
    var srcColumn = 0;
    var srcNameId = 0;
    var tokenizer = _MappingTokenizer(map['mappings'] as String);
    var entries = <TargetEntry>[];

    while (tokenizer.hasTokens) {
      if (tokenizer.nextKind.isNewLine) {
        if (entries.isNotEmpty) {
          lines.add(TargetLineEntry(line, entries));
          entries = <TargetEntry>[];
        }
        line++;
        column = 0;
        tokenizer._consumeNewLine();
        continue;
      }

      // Decode the next entry, using the previous encountered values to
      // decode the relative values.
      //
      // We expect 1, 4, or 5 values. If present, values are expected in the
      // following order:
      //   0: the starting column in the current line of the generated file
      //   1: the id of the original source file
      //   2: the starting line in the original source
      //   3: the starting column in the original source
      //   4: the id of the original symbol name
      // The values are relative to the previous encountered values.
      if (tokenizer.nextKind.isNewSegment) throw _segmentError(0, line);
      column += tokenizer._consumeValue();
      if (!tokenizer.nextKind.isValue) {
        entries.add(TargetEntry(column));
      } else {
        srcUrlId += tokenizer._consumeValue();
        if (srcUrlId >= urls.length) {
          throw StateError(
              'Invalid source url id. $targetUrl, $line, $srcUrlId');
        }
        if (!tokenizer.nextKind.isValue) throw _segmentError(2, line);
        srcLine += tokenizer._consumeValue();
        if (!tokenizer.nextKind.isValue) throw _segmentError(3, line);
        srcColumn += tokenizer._consumeValue();
        if (!tokenizer.nextKind.isValue) {
          entries.add(TargetEntry(column, srcUrlId, srcLine, srcColumn));
        } else {
          srcNameId += tokenizer._consumeValue();
          if (srcNameId >= names.length) {
            throw StateError('Invalid name id: $targetUrl, $line, $srcNameId');
          }
          entries.add(
              TargetEntry(column, srcUrlId, srcLine, srcColumn, srcNameId));
        }
      }
      if (tokenizer.nextKind.isNewSegment) tokenizer._consumeNewSegment();
    }
    if (entries.isNotEmpty) {
      lines.add(TargetLineEntry(line, entries));
    }

    map.forEach((name, value) {
      if (name.startsWith('x_')) extensions[name] = value;
    });
  }

  /// Encodes the Mapping mappings as a json map.
  ///
  /// If [includeSourceContents] is `true`, this includes the source file
  /// contents from [files] in the map if possible.
  Map<String, dynamic> toJson({bool includeSourceContents = false}) {
    var buff = StringBuffer();
    var line = 0;
    var column = 0;
    var srcLine = 0;
    var srcColumn = 0;
    var srcUrlId = 0;
    var srcNameId = 0;
    var first = true;

    for (var entry in lines) {
      var nextLine = entry.line;
      if (nextLine > line) {
        for (var i = line; i < nextLine; ++i) {
          buff.write(';');
        }
        line = nextLine;
        column = 0;
        first = true;
      }

      for (var segment in entry.entries) {
        if (!first) buff.write(',');
        first = false;
        column = _append(buff, column, segment.column);

        // Encoding can be just the column offset if there is no source
        // information.
        var newUrlId = segment.sourceUrlId;
        if (newUrlId == null) continue;
        srcUrlId = _append(buff, srcUrlId, newUrlId);
        srcLine = _append(buff, srcLine, segment.sourceLine!);
        srcColumn = _append(buff, srcColumn, segment.sourceColumn!);

        if (segment.sourceNameId == null) continue;
        srcNameId = _append(buff, srcNameId, segment.sourceNameId!);
      }
    }

    var result = <String, dynamic>{
      'version': 3,
      'sourceRoot': sourceRoot ?? '',
      'sources': urls,
      'names': names,
      'mappings': buff.toString(),
    };
    if (targetUrl != null) result['file'] = targetUrl!;

    if (includeSourceContents) {
      result['sourcesContent'] = files.map((file) => file?.getText(0)).toList();
    }
    extensions.forEach((name, value) => result[name] = value);

    return result;
  }

  /// Appends to [buff] a VLQ encoding of [newValue] using the difference
  /// between [oldValue] and [newValue]
  static int _append(StringBuffer buff, int oldValue, int newValue) {
    buff.writeAll(encodeVlq(newValue - oldValue));
    return newValue;
  }

  StateError _segmentError(int seen, int line) =>
      StateError('Invalid entry in sourcemap, expected 1, 4, or 5'
          ' values, but got $seen.\ntargeturl: $targetUrl, line: $line');

  /// Returns the last [TargetEntry] which includes the location denoted by
  /// [line], [column].
  ///
  /// This corresponds to the computation of _last_ in [GetOriginalPositions][1]
  /// in the sourcemap specification.
  ///
  ///  [1]: https://tc39.es/ecma426/#sec-GetOriginalPositions
  TargetEntry? _findEntry(int line, int column) {
    // To find the *last* TargetEntry, we scan backwards, starting from the
    // first line after our target line, or the end of [lines].
    var lineIndex = binarySearch(lines, (e) => e.line > line);
    while (--lineIndex >= 0) {
      final lineEntry = lines[lineIndex];
      final entries = lineEntry.entries;
      if (entries.isEmpty) continue;
      // If we scan to a line before the target line, the last entry extends to
      // cover our search location.
      if (lineEntry.line != line) return entries.last;
      final index = binarySearch(entries, (e) => e.column > column);
      if (index > 0) return entries[index - 1];
      // We get here when the line has entries, but they are all after the
      // column. When this happens, the line and column correspond to the
      // previous entry, usually the last entry at the previous `lineIndex`.
    }
    return null;
  }

  @override
  SourceMapSpan? spanFor(int line, int column,
      {Map<String, SourceFile>? files, String? uri}) {
    final entry = _findEntry(line, column);
    if (entry == null) return null;

    var sourceUrlId = entry.sourceUrlId;
    if (sourceUrlId == null) return null;

    var url = urls[sourceUrlId];
    if (sourceRoot != null) {
      url = '$sourceRoot$url';
    }

    var sourceNameId = entry.sourceNameId;
    var file = files?[url];
    if (file != null) {
      var start = file.getOffset(entry.sourceLine!, entry.sourceColumn);
      if (sourceNameId != null) {
        var text = names[sourceNameId];
        return SourceMapFileSpan(file.span(start, start + text.length),
            isIdentifier: true);
      } else {
        return SourceMapFileSpan(file.location(start).pointSpan());
      }
    } else {
      var start = SourceLocation(0,
          sourceUrl: _mapUrl?.resolve(url) ?? url,
          line: entry.sourceLine,
          column: entry.sourceColumn);

      // Offset and other context is not available.
      if (sourceNameId != null) {
        return SourceMapSpan.identifier(start, names[sourceNameId]);
      } else {
        return SourceMapSpan(start, start, '');
      }
    }
  }

  @override
  String toString() {
    return (StringBuffer('$runtimeType : [')
          ..write('targetUrl: ')
          ..write(targetUrl)
          ..write(', sourceRoot: ')
          ..write(sourceRoot)
          ..write(', urls: ')
          ..write(urls)
          ..write(', names: ')
          ..write(names)
          ..write(', lines: ')
          ..write(lines)
          ..write(']'))
        .toString();
  }

  String get debugString {
    var buff = StringBuffer();
    for (var lineEntry in lines) {
      var line = lineEntry.line;
      for (var entry in lineEntry.entries) {
        buff
          ..write(targetUrl)
          ..write(': ')
          ..write(line)
          ..write(':')
          ..write(entry.column);
        var sourceUrlId = entry.sourceUrlId;
        if (sourceUrlId != null) {
          buff
            ..write('   -->   ')
            ..write(sourceRoot)
            ..write(urls[sourceUrlId])
            ..write(': ')
            ..write(entry.sourceLine)
            ..write(':')
            ..write(entry.sourceColumn);
        }
        var sourceNameId = entry.sourceNameId;
        if (sourceNameId != null) {
          buff
            ..write(' (')
            ..write(names[sourceNameId])
            ..write(')');
        }
        buff.write('\n');
      }
    }
    return buff.toString();
  }
}

/// A line entry read from a source map.
class TargetLineEntry {
  final int line;
  List<TargetEntry> entries;
  TargetLineEntry(this.line, this.entries);

  @override
  String toString() => '$runtimeType: $line $entries';
}

/// A target segment entry read from a source map
class TargetEntry {
  final int column;
  final int? sourceUrlId;
  final int? sourceLine;
  final int? sourceColumn;
  final int? sourceNameId;

  TargetEntry(this.column,
      [this.sourceUrlId,
      this.sourceLine,
      this.sourceColumn,
      this.sourceNameId]);

  @override
  String toString() => '$runtimeType: '
      '($column, $sourceUrlId, $sourceLine, $sourceColumn, $sourceNameId)';
}

/// A character iterator over a string that can peek one character ahead.
class _MappingTokenizer implements Iterator<String> {
  final String _internal;
  final int _length;
  int index = -1;
  _MappingTokenizer(String internal)
      : _internal = internal,
        _length = internal.length;

  // Iterator API is used by decodeVlq to consume VLQ entries.
  @override
  bool moveNext() => ++index < _length;

  @override
  String get current => (index >= 0 && index < _length)
      ? _internal[index]
      : throw RangeError.index(index, _internal);

  bool get hasTokens => index < _length - 1 && _length > 0;

  _TokenKind get nextKind {
    if (!hasTokens) return _TokenKind.eof;
    var next = _internal[index + 1];
    if (next == ';') return _TokenKind.line;
    if (next == ',') return _TokenKind.segment;
    return _TokenKind.value;
  }

  int _consumeValue() => decodeVlq(this);
  void _consumeNewLine() {
    ++index;
  }

  void _consumeNewSegment() {
    ++index;
  }

  // Print the state of the iterator, with colors indicating the current
  // position.
  @override
  String toString() {
    var buff = StringBuffer();
    for (var i = 0; i < index; i++) {
      buff.write(_internal[i]);
    }
    buff.write('[31m');
    try {
      buff.write(current);
      // TODO: Determine whether this try / catch can be removed.
      // ignore: avoid_catching_errors
    } on RangeError catch (_) {}
    buff.write('[0m');
    for (var i = index + 1; i < _internal.length; i++) {
      buff.write(_internal[i]);
    }
    buff.write(' ($index)');
    return buff.toString();
  }
}

class _TokenKind {
  static const _TokenKind line = _TokenKind(isNewLine: true);
  static const _TokenKind segment = _TokenKind(isNewSegment: true);
  static const _TokenKind eof = _TokenKind(isEof: true);
  static const _TokenKind value = _TokenKind();
  final bool isNewLine;
  final bool isNewSegment;
  final bool isEof;
  bool get isValue => !isNewLine && !isNewSegment && !isEof;

  const _TokenKind(
      {this.isNewLine = false, this.isNewSegment = false, this.isEof = false});
}
