// 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 code printer that generates code by recording the source maps.
library source_maps.printer;

import 'package:source_span/source_span.dart';

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

/// A simple printer that keeps track of offset locations and records source
/// maps locations.
class Printer {
  final String filename;
  final StringBuffer _buff = StringBuffer();
  final SourceMapBuilder _maps = SourceMapBuilder();
  String get text => _buff.toString();
  String get map => _maps.toJson(filename);

  /// Current source location mapping.
  SourceLocation? _loc;

  /// Current line in the buffer;
  int _line = 0;

  /// Current column in the buffer.
  int _column = 0;

  Printer(this.filename);

  /// Add [str] contents to the output, tracking new lines to track correct
  /// positions for span locations. When [projectMarks] is true, this method
  /// adds a source map location on each new line, projecting that every new
  /// line in the target file (printed here) corresponds to a new line in the
  /// source file.
  void add(String str, {bool projectMarks = false}) {
    var chars = str.runes.toList();
    var length = chars.length;
    for (var i = 0; i < length; i++) {
      var c = chars[i];
      if (c == lineFeed ||
          (c == carriageReturn &&
              (i + 1 == length || chars[i + 1] != lineFeed))) {
        // Return not followed by line-feed is treated as a new line.
        _line++;
        _column = 0;
        {
          // **Warning**: Any calls to `mark` will change the value of `_loc`,
          // so this local variable is no longer up to date after that point.
          //
          // This is why it has been put inside its own block to limit the
          // scope in which it is available.
          var loc = _loc;
          if (projectMarks && loc != null) {
            if (loc is FileLocation) {
              var file = loc.file;
              mark(file.location(file.getOffset(loc.line + 1)));
            } else {
              mark(SourceLocation(0,
                  sourceUrl: loc.sourceUrl, line: loc.line + 1, column: 0));
            }
          }
        }
      } else {
        _column++;
      }
    }
    _buff.write(str);
  }

  /// Append a [total] number of spaces in the target file. Typically used for
  /// formatting indentation.
  void addSpaces(int total) {
    for (var i = 0; i < total; i++) {
      _buff.write(' ');
    }
    _column += total;
  }

  /// Marks that the current point in the target file corresponds to the [mark]
  /// in the source file, which can be either a [SourceLocation] or a
  /// [SourceSpan]. When the mark is a [SourceMapSpan] with `isIdentifier` set,
  /// this also records the name of the identifier in the source map
  /// information.
  void mark(Object mark) {
    late final SourceLocation loc;
    String? identifier;
    if (mark is SourceLocation) {
      loc = mark;
    } else if (mark is SourceSpan) {
      loc = mark.start;
      if (mark is SourceMapSpan && mark.isIdentifier) identifier = mark.text;
    }
    _maps.addLocation(loc,
        SourceLocation(_buff.length, line: _line, column: _column), identifier);
    _loc = loc;
  }
}

/// A more advanced printer that keeps track of offset locations to record
/// source maps, but additionally allows nesting of different kind of items,
/// including [NestedPrinter]s, and it let's you automatically indent text.
///
/// This class is especially useful when doing code generation, where different
/// pieces of the code are generated independently on separate printers, and are
/// finally put together in the end.
class NestedPrinter implements NestedItem {
  /// Items recoded by this printer, which can be [String] literals,
  /// [NestedItem]s, and source map information like [SourceLocation] and
  /// [SourceSpan].
  final List<Object> _items = [];

  /// Internal buffer to merge consecutive strings added to this printer.
  StringBuffer? _buff;

  /// Current indentation, which can be updated from outside this class.
  int indent;

  /// [Printer] used during the last call to [build], if any.
  Printer? printer;

  /// Returns the text produced after calling [build].
  String? get text => printer?.text;

  /// Returns the source-map information produced after calling [build].
  String? get map => printer?.map;

  /// Item used to indicate that the following item is copied from the original
  /// source code, and hence we should preserve source-maps on every new line.
  static final _original = Object();

  NestedPrinter([this.indent = 0]);

  /// Adds [object] to this printer. [object] can be a [String],
  /// [NestedPrinter], or anything implementing [NestedItem]. If [object] is a
  /// [String], the value is appended directly, without doing any formatting
  /// changes. If you wish to add a line of code with automatic indentation, use
  /// [addLine] instead.  [NestedPrinter]s and [NestedItem]s are not processed
  /// until [build] gets called later on. We ensure that [build] emits every
  /// object in the order that they were added to this printer.
  ///
  /// The [location] and [span] parameters indicate the corresponding source map
  /// location of [object] in the original input. Only one, [location] or
  /// [span], should be provided at a time.
  ///
  /// Indicate [isOriginal] when [object] is copied directly from the user code.
  /// Setting [isOriginal] will make this printer propagate source map locations
  /// on every line-break.
  void add(Object object,
      {SourceLocation? location, SourceSpan? span, bool isOriginal = false}) {
    if (object is! String || location != null || span != null || isOriginal) {
      _flush();
      assert(location == null || span == null);
      if (location != null) _items.add(location);
      if (span != null) _items.add(span);
      if (isOriginal) _items.add(_original);
    }

    if (object is String) {
      _appendString(object);
    } else {
      _items.add(object);
    }
  }

  /// Append `2 * indent` spaces to this printer.
  void insertIndent() => _indent(indent);

  /// Add a [line], autoindenting to the current value of [indent]. Note,
  /// indentation is not inferred from the contents added to this printer. If a
  /// line starts or ends an indentation block, you need to also update [indent]
  /// accordingly. Also, indentation is not adapted for nested printers. If
  /// you add a [NestedPrinter] to this printer, its indentation is set
  /// separately and will not include any the indentation set here.
  ///
  /// The [location] and [span] parameters indicate the corresponding source map
  /// location of [line] in the original input. Only one, [location] or
  /// [span], should be provided at a time.
  void addLine(String? line, {SourceLocation? location, SourceSpan? span}) {
    if (location != null || span != null) {
      _flush();
      assert(location == null || span == null);
      if (location != null) _items.add(location);
      if (span != null) _items.add(span);
    }
    if (line == null) return;
    if (line != '') {
      // We don't indent empty lines.
      _indent(indent);
      _appendString(line);
    }
    _appendString('\n');
  }

  /// Appends a string merging it with any previous strings, if possible.
  void _appendString(String s) {
    var buf = _buff ??= StringBuffer();
    buf.write(s);
  }

  /// Adds all of the current [_buff] contents as a string item.
  void _flush() {
    if (_buff != null) {
      _items.add(_buff.toString());
      _buff = null;
    }
  }

  void _indent(int indent) {
    for (var i = 0; i < indent; i++) {
      _appendString('  ');
    }
  }

  /// Returns a string representation of all the contents appended to this
  /// printer, including source map location tokens.
  @override
  String toString() {
    _flush();
    return (StringBuffer()..writeAll(_items)).toString();
  }

  /// Builds the output of this printer and source map information. After
  /// calling this function, you can use [text] and [map] to retrieve the
  /// geenrated code and source map information, respectively.
  void build(String filename) {
    writeTo(printer = Printer(filename));
  }

  /// Implements the [NestedItem] interface.
  @override
  void writeTo(Printer printer) {
    _flush();
    var propagate = false;
    for (var item in _items) {
      if (item is NestedItem) {
        item.writeTo(printer);
      } else if (item is String) {
        printer.add(item, projectMarks: propagate);
        propagate = false;
      } else if (item is SourceLocation || item is SourceSpan) {
        printer.mark(item);
      } else if (item == _original) {
        // we insert booleans when we are about to quote text that was copied
        // from the original source. In such case, we will propagate marks on
        // every new-line.
        propagate = true;
      } else {
        throw UnsupportedError('Unknown item type: $item');
      }
    }
  }
}

/// An item added to a [NestedPrinter].
abstract class NestedItem {
  /// Write the contents of this item into [printer].
  void writeTo(Printer printer);
}
