// 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 dart2js.source_map_builder;

import '../util/util.dart';
import '../util/uri_extras.dart' show relativize;
import 'line_column_provider.dart';
import 'source_information.dart' show SourceFileLocation;

class SourceMapBuilder {
  static const int VLQ_BASE_SHIFT = 5;
  static const int VLQ_BASE_MASK = (1 << 5) - 1;
  static const int VLQ_CONTINUATION_BIT = 1 << 5;
  static const int VLQ_CONTINUATION_MASK = 1 << 5;
  static const String BASE64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn'
                                      'opqrstuvwxyz0123456789+/';

  final Uri uri;
  final Uri fileUri;

  LineColumnProvider lineColumnProvider;
  List<SourceMapEntry> entries;

  Map<String, int> sourceUrlMap;
  List<String> sourceUrlList;
  Map<String, int> sourceNameMap;
  List<String> sourceNameList;

  int previousTargetLine;
  int previousTargetColumn;
  int previousSourceUrlIndex;
  int previousSourceLine;
  int previousSourceColumn;
  int previousSourceNameIndex;
  bool firstEntryInLine;

  SourceMapBuilder(this.uri, this.fileUri, this.lineColumnProvider) {
    entries = new List<SourceMapEntry>();

    sourceUrlMap = new Map<String, int>();
    sourceUrlList = new List<String>();
    sourceNameMap = new Map<String, int>();
    sourceNameList = new List<String>();

    previousTargetLine = 0;
    previousTargetColumn = 0;
    previousSourceUrlIndex = 0;
    previousSourceLine = 0;
    previousSourceColumn = 0;
    previousSourceNameIndex = 0;
    firstEntryInLine = true;
  }

  resetPreviousSourceLocation() {
    previousSourceUrlIndex = 0;
    previousSourceLine = 0;
    previousSourceColumn = 0;
    previousSourceNameIndex = 0;
  }

  updatePreviousSourceLocation(SourceFileLocation sourceLocation) {
    previousSourceLine = sourceLocation.getLine();
    previousSourceColumn = sourceLocation.getColumn();
    String sourceUrl = sourceLocation.getSourceUrl();
    previousSourceUrlIndex = indexOf(sourceUrlList, sourceUrl, sourceUrlMap);
    String sourceName = sourceLocation.getSourceName();
    if (sourceName != null) {
      previousSourceNameIndex =
          indexOf(sourceNameList, sourceName, sourceNameMap);
    }
  }

  bool sameAsPreviousLocation(SourceFileLocation sourceLocation) {
    if (sourceLocation == null) {
      return true;
    }
    int sourceUrlIndex =
        indexOf(sourceUrlList, sourceLocation.getSourceUrl(), sourceUrlMap);
    return
       sourceUrlIndex == previousSourceUrlIndex &&
       sourceLocation.getLine() == previousSourceLine &&
       sourceLocation.getColumn() == previousSourceColumn;
  }

  void addMapping(int targetOffset, SourceFileLocation sourceLocation) {

    bool sameLine(int position, otherPosition) {
      return lineColumnProvider.getLine(position) ==
                 lineColumnProvider.getLine(otherPosition);
    }

    if (!entries.isEmpty && sameLine(targetOffset, entries.last.targetOffset)) {
      if (sameAsPreviousLocation(sourceLocation)) {
        // The entry points to the same source location as the previous entry in
        // the same line, hence it is not needed for the source map.
        //
        // TODO(zarah): Remove this check and make sure that [addMapping] is not
        // called for this position. Instead, when consecutive lines in the
        // generated code point to the same source location, record this and use
        // it to generate the entries of the source map.
        return;
      }
    }

    if (sourceLocation != null) {
      updatePreviousSourceLocation(sourceLocation);
    }
    entries.add(new SourceMapEntry(sourceLocation, targetOffset));
  }

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

  String build() {
    resetPreviousSourceLocation();
    StringBuffer mappingsBuffer = new StringBuffer();
    entries.forEach((SourceMapEntry entry) {
      writeEntry(entry, mappingsBuffer);
    });
    StringBuffer buffer = new StringBuffer();
    buffer.write('{\n');
    buffer.write('  "version": 3,\n');
    if (uri != null && fileUri != null) {
      buffer.write('  "file": "${relativize(uri, fileUri, false)}",\n');
    }
    buffer.write('  "sourceRoot": "",\n');
    buffer.write('  "sources": ');
    if (uri != null) {
      sourceUrlList =
          sourceUrlList.map((url) => relativize(uri, Uri.parse(url), false))
              .toList();
    }
    printStringListOn(sourceUrlList, buffer);
    buffer.write(',\n');
    buffer.write('  "names": ');
    printStringListOn(sourceNameList, buffer);
    buffer.write(',\n');
    buffer.write('  "mappings": "');
    buffer.write(mappingsBuffer);
    buffer.write('"\n}\n');
    return buffer.toString();
  }

  void writeEntry(SourceMapEntry entry, StringBuffer output) {
    int targetLine = lineColumnProvider.getLine(entry.targetOffset);
    int targetColumn =
        lineColumnProvider.getColumn(targetLine, entry.targetOffset);

    if (targetLine > previousTargetLine) {
      for (int i = previousTargetLine; i < targetLine; ++i) {
        output.write(';');
      }
      previousTargetLine = targetLine;
      previousTargetColumn = 0;
      firstEntryInLine = true;
    }

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

    encodeVLQ(output, targetColumn - previousTargetColumn);
    previousTargetColumn = targetColumn;

    if (entry.sourceLocation == null) return;

    String sourceUrl = entry.sourceLocation.getSourceUrl();
    int sourceLine = entry.sourceLocation.getLine();
    int sourceColumn = entry.sourceLocation.getColumn();
    String sourceName = entry.sourceLocation.getSourceName();

    int sourceUrlIndex = indexOf(sourceUrlList, sourceUrl, sourceUrlMap);
    encodeVLQ(output, sourceUrlIndex - previousSourceUrlIndex);
    encodeVLQ(output, sourceLine - previousSourceLine);
    encodeVLQ(output, sourceColumn - previousSourceColumn);

    if (sourceName != null) {
      int sourceNameIndex = indexOf(sourceNameList, sourceName, sourceNameMap);
      encodeVLQ(output, sourceNameIndex - previousSourceNameIndex);
    }

    // Update previous source location to ensure the next indices are relative
    // to those if [entry.sourceLocation].
    updatePreviousSourceLocation(entry.sourceLocation);
  }

  int indexOf(List<String> list, String value, Map<String, int> map) {
    return map.putIfAbsent(value, () {
      int index = list.length;
      list.add(value);
      return index;
    });
  }

  static void encodeVLQ(StringBuffer output, int value) {
    int signBit = 0;
    if (value < 0) {
      signBit = 1;
      value = -value;
    }
    value = (value << 1) | signBit;
    do {
      int digit = value & VLQ_BASE_MASK;
      value >>= VLQ_BASE_SHIFT;
      if (value > 0) {
        digit |= VLQ_CONTINUATION_BIT;
      }
      output.write(BASE64_DIGITS[digit]);
    } while (value > 0);
  }
}

class SourceMapEntry {
  SourceFileLocation sourceLocation;
  int targetOffset;

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