// 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 a builder object useful for creating source maps programatically.
library source_maps.builder;

// TODO(sigmund): add a builder for multi-section mappings.

import 'dart:convert';

import 'package:source_span/source_span.dart';

import 'parser.dart';
import 'src/source_map_span.dart';

/// Builds a source map given a set of mappings.
class SourceMapBuilder {
  final List<Entry> _entries = <Entry>[];

  /// Adds an entry mapping the [targetOffset] to [source].
  void addFromOffset(SourceLocation source, SourceFile targetFile,
      int targetOffset, String identifier) {
    if (targetFile == null) {
      throw new ArgumentError('targetFile cannot be null');
    }
    _entries
        .add(new Entry(source, targetFile.location(targetOffset), identifier));
  }

  /// Adds an entry mapping [target] to [source].
  ///
  /// If [isIdentifier] is true or if [target] is a [SourceMapSpan] with
  /// `isIdentifier` set to true, this entry is considered to represent an
  /// identifier whose value will be stored in the source map. [isIdenfier]
  /// takes precedence over [target]'s `isIdentifier` value.
  void addSpan(SourceSpan source, SourceSpan target, {bool isIdentifier}) {
    if (isIdentifier == null) {
      isIdentifier = source is SourceMapSpan ? source.isIdentifier : false;
    }

    var name = isIdentifier ? source.text : null;
    _entries.add(new Entry(source.start, target.start, name));
  }

  /// Adds an entry mapping [target] to [source].
  void addLocation(
      SourceLocation source, SourceLocation target, String identifier) {
    _entries.add(new Entry(source, target, identifier));
  }

  /// Encodes all mappings added to this builder as a json map.
  Map build(String fileUrl) {
    return new SingleMapping.fromEntries(this._entries, fileUrl).toJson();
  }

  /// Encodes all mappings added to this builder as a json string.
  String toJson(String fileUrl) => JSON.encode(build(fileUrl));
}

/// An entry in the source map builder.
class Entry implements Comparable<Entry> {
  /// Span denoting the original location in the input source file
  final SourceLocation source;

  /// Span indicating the corresponding location in the target file.
  final SourceLocation target;

  /// An identifier name, when this location is the start of an identifier.
  final String identifierName;

  /// Creates a new [Entry] mapping [target] to [source].
  Entry(this.source, this.target, this.identifierName);

  /// Implements [Comparable] to ensure that entries are ordered by their
  /// location in the target file. We sort primarily by the target offset
  /// because source map files are encoded by printing each mapping in order as
  /// they appear in the target file.
  int compareTo(Entry other) {
    int res = target.compareTo(other.target);
    if (res != 0) return res;
    res = source.sourceUrl
        .toString()
        .compareTo(other.source.sourceUrl.toString());
    if (res != 0) return res;
    return source.compareTo(other.source);
  }
}
