// Copyright (c) 2014, 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 dart_style.src.chunk;

import 'debug.dart';

/// Tracks where a selection start or end point may appear in some piece of
/// text.
abstract class Selection {
  /// The chunk of text.
  String get text;

  /// The offset from the beginning of [text] where the selection starts, or
  /// `null` if the selection does not start within this chunk.
  int get selectionStart => _selectionStart;
  int _selectionStart;

  /// The offset from the beginning of [text] where the selection ends, or
  /// `null` if the selection does not start within this chunk.
  int get selectionEnd => _selectionEnd;
  int _selectionEnd;

  /// Sets [selectionStart] to be [start] characters into [text].
  void startSelection(int start) {
    _selectionStart = start;
  }

  /// Sets [selectionStart] to be [fromEnd] characters from the end of [text].
  void startSelectionFromEnd(int fromEnd) {
    _selectionStart = text.length - fromEnd;
  }

  /// Sets [selectionEnd] to be [end] characters into [text].
  void endSelection(int end) {
    _selectionEnd = end;
  }

  /// Sets [selectionEnd] to be [fromEnd] characters from the end of [text].
  void endSelectionFromEnd(int fromEnd) {
    _selectionEnd = text.length - fromEnd;
  }
}

/// A chunk of non-breaking output text terminated by a hard or soft newline.
///
/// Chunks are created by [LineWriter] and fed into [LineSplitter]. Each
/// contains some text, along with the data needed to tell how the next line
/// should be formatted and how desireable it is to split after the chunk.
///
/// Line splitting after chunks comes in a few different forms.
///
/// *   A "hard" split is a mandatory newline. The formatted output will contain
///     at least one newline after the chunk's text.
/// *   A "soft" split is a discretionary newline. If a line doesn't fit within
///     the page width, one or more soft splits may be turned into newlines to
///     wrap the line to fit within the bounds. If a soft split is not turned
///     into a newline, it may instead appear as a space or zero-length string
///     in the output, depending on [spaceWhenUnsplit].
/// *   A "double" split expands to two newlines. In other words, it leaves a
///     blank line in the output. Hard or soft splits may be doubled. This is
///     determined by [isDouble].
///
/// A split controls the leading spacing of the subsequent line, both
/// block-based [indent] and expression-wrapping-based [nesting].
class Chunk extends Selection {
  /// The literal text output for the chunk.
  String get text => _text;
  String _text;

  /// The indentation level of the line following this chunk.
  ///
  /// Note that this is not a relative indentation *offset*. It's the full
  /// indentation. When a chunk is newly created from text, this is `null` to
  /// indicate that the chunk has no splitting information yet.
  int get indent => _indent;
  int _indent = null;

  /// The number of levels of expression nesting following this chunk.
  ///
  /// This is used to determine how much to increase the indentation when a
  /// line starts after this chunk. A single statement may be indented multiple
  /// times if the splits occur in more deeply nested expressions, for example:
  ///
  ///     // 40 columns                           |
  ///     someFunctionName(argument, argument,
  ///         argument, anotherFunction(argument,
  ///             argument));
  int nesting = -1;

  /// Whether or not the chunk occurs inside an expression.
  ///
  /// Splits within expressions must take into account how deeply nested they
  /// are to determine the indentation of subsequent lines. "Statement level"
  /// splits that occur between statements or in the top-level of a unit only
  /// take the main indent level into account.
  bool get isInExpression => nesting != -1;

  /// Whether it's valid to add more text to this chunk or not.
  ///
  /// Chunks are built up by adding text and then "capped off" by having their
  /// split information set by calling [handleSplit]. Once the latter has been
  /// called, no more text should be added to the chunk since it would appear
  /// *before* the split.
  bool get canAddText => _indent == null;

  /// The [SplitParam] that determines if this chunk is being used as a split
  /// or not.
  ///
  /// Multiple splits may share a [SplitParam] because they are part of the
  /// same [Multisplit], in which case they are split or unsplit in unison.
  ///
  /// This is `null` for hard splits.
  SplitParam get param => _param;
  SplitParam _param;

  /// Whether this chunk is always followed by a newline or whether the line
  /// splitter may choose to keep the next chunk on the same line.
  bool get isHardSplit => _indent != null && _param == null;

  /// Whether this chunk may cause a newline depending on line splitting.
  bool get isSoftSplit => _indent != null && _param != null;

  /// `true` if an extra blank line should be output after this chunk if it's
  /// split.
  bool get isDouble => _isDouble;
  bool _isDouble = false;

  /// Whether this chunk should append an extra space if it's a soft split and
  /// is left unsplit.
  ///
  /// This is `true`, for example, in a chunk that ends with a ",".
  bool get spaceWhenUnsplit => _spaceWhenUnsplit;
  bool _spaceWhenUnsplit = false;

  /// Creates a new chunk starting with [_text].
  Chunk(this._text);

  /// Discard the split for the chunk and put it back into the state where more
  /// text can be appended.
  void allowText() {
    _indent = null;
  }

  /// Append [text] to the end of the split's text.
  void appendText(String text) {
    assert(canAddText);

    _text += text;
  }

  /// Forces this soft split to become a hard split.
  ///
  /// This is called on the soft splits of a [Multisplit] when it ends up
  /// containing some other hard split.
  void harden() {
    assert(_param != null);
    _param = null;
  }

  /// Finishes off this chunk with the given split information.
  ///
  /// This may be called multiple times on the same split since the splits
  /// produced by walking the source and the splits coming from comments and
  /// preserved whitespace often overlap. When that happens, this has logic to
  /// combine that information into a single split.
  void applySplit(int indent, int nesting, SplitParam param,
      {bool spaceWhenUnsplit, bool isDouble}) {
    if (spaceWhenUnsplit == null) spaceWhenUnsplit = false;
    if (isDouble == null) isDouble = false;

    if (isHardSplit || param == null) {
      // A hard split always wins.
      _param = null;
    } else if (_indent == null) {
      // If the chunk hasn't been initialized yet, just inherit the param.
      _param = param;
    }

    // Last newline settings win.
    _indent = indent;
    this.nesting = nesting;
    _spaceWhenUnsplit = spaceWhenUnsplit;

    // Preserve a blank line.
    _isDouble = _isDouble || isDouble;
  }

  String toString() {
    var parts = [];

    if (text.isNotEmpty) parts.add("${Color.bold}$text${Color.none}");

    if (_indent != 0 && _indent != null) parts.add("indent:$_indent");
    if (nesting != -1) parts.add("nest:$nesting");
    if (spaceWhenUnsplit) parts.add("space");
    if (_isDouble) parts.add("double");

    if (_indent == null) {
      parts.add("(no split info)");
    } else if (isHardSplit) {
      parts.add("hard");
    } else {
      var param = "p$_param";

      if (_param.cost != Cost.normal) param += " \$${_param.cost}";

      if (_param.implies.isNotEmpty) {
        var impliedIds = _param.implies.map(
            (param) => "p${param.id}").join(" ");
        param += " -> $impliedIds";
      }

      parts.add(param);
    }

    return parts.join(" ");
  }
}

/// Constants for the cost heuristics used to determine which set of splits is
/// most desirable.
class Cost {
  /// The smallest cost.
  ///
  /// This isn't zero because we want to ensure all splitting has *some* cost,
  /// otherwise, the formatter won't try to keep things on one line at all.
  /// Almost all splits and spans use this. Greater costs tend to come from a
  /// greater number of nested spans.
  static const normal = 1;

  /// Splitting after a "=" both for assignment and initialization.
  static const assignment = 2;

  /// Splitting before the first argument when it happens to be a function
  /// expression with a block body.
  static const firstBlockArgument = 2;

  /// The series of positional arguments.
  static const positionalArguments = 2;

  /// Splitting inside the brackets of a list with only one element.
  static const singleElementList = 2;

  /// The cost of a single character that goes past the page limit.
  ///
  /// This cost is high to ensure any solution that fits in the page is
  /// preferred over one that does not.
  static const overflowChar = 1000;
}

/// Controls whether or not one or more soft split [Chunk]s are split.
///
/// When [LineSplitter] tries to split a line to fit within its page width, it
/// does so by trying different combinations of parameters to see which set of
/// active ones yields the best result.
class SplitParam {
  static int _nextId = 0;

  /// A semi-unique numeric indentifier for the param.
  ///
  /// This is useful for debugging and also speeds up using the param in hash
  /// sets. Ids are *semi*-unique because they may wrap around in long running
  /// processes. Since params are equal based on their identity, this is
  /// innocuous and prevents ids from growing without bound.
  final int id = _nextId = (_nextId + 1) & 0x0fffffff;

  /// The cost of this param when split.
  final int cost;

  /// The other [SplitParam]s that are "implied" by this one.
  ///
  /// Implication means that if the splitter chooses to split this param, it
  /// must also split all of its implied ones (transitively). Implication is
  /// one-way. If A implies B, it's fine to split B without splitting A.
  final implies = <SplitParam>[];

  /// Creates a new [SplitParam].
  SplitParam([int cost])
      : cost = cost != null ? cost : Cost.normal;

  String toString() => "$id";

  int get hashCode => id.hashCode;

  bool operator ==(other) => identical(this, other);
}

/// Delimits a range of chunks that must end up on the same line to avoid an
/// additional cost.
///
/// These are used to encourage the line splitter to try to keep things
/// together, like parameter lists and binary operator expressions.
class Span {
  /// Index of the first chunk contained in this span.
  int get start => _start;
  int _start;

  /// Index of the last chunk contained in this span.
  int get end => _end;
  int _end;

  /// The cost applied when the span is split across multiple lines or `null`
  /// if the span is for a multisplit.
  final int cost;

  Span(this._start, this.cost);

  /// Marks this span as ending at [end].
  void close(int end) {
    assert(_end == null);
    _end = end;
  }

  String toString() {
    var result = "Span($start";

    if (end != null) {
      result += " - $end";
    } else {
      result += "...";
    }

    if (cost != null) result += " \$$cost";

    return result + ")";
  }

  /// Shifts the indexes of the chunk down by [offset].
  ///
  /// This is used when a prefix of the chunk list gets pulled off by the
  /// [LineWriter] after it gets formatted as a line. The remaining spans need
  /// to have their indices shifted to account for the removed chunks.
  ///
  /// Returns `true` if the span has shifted all the way off the front and
  /// should just be discarded.
  bool shift(int offset) {
    if (end != null && end < offset) return true;

    _start -= offset;
    if (_end != null) _end -= offset;

    return false;
  }
}

/// A comment in the source, with a bit of information about the surrounding
/// whitespace.
class SourceComment extends Selection {
  /// The text of the comment, including `//`, `/*`, and `*/`.
  final String text;

  /// The number of newlines between the comment or token preceding this comment
  /// and the beginning of this one.
  ///
  /// Will be zero if the comment is a trailing one.
  final int linesBefore;

  /// Whether this comment is a line comment.
  final bool isLineComment;

  /// Whether this comment starts at column one in the source.
  ///
  /// Comments that start at the start of the line will not be indented in the
  /// output. This way, commented out chunks of code do not get erroneously
  /// re-indented.
  final bool isStartOfLine;

  SourceComment(this.text, this.linesBefore,
      {this.isLineComment, this.isStartOfLine});
}
