// 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.line_prefix;

import 'chunk.dart';
import 'nesting.dart';
import 'rule/rule.dart';

/// A prefix of a series of chunks and the context needed to uniquely describe
/// any shared state between the preceding and following chunks.
///
/// This is used by [LineSplitter] to memoize suffixes whose best splits have
/// previously been calculated. For each unique [LinePrefix], there is a single
/// set of best splits for the remainder of the line following it.
///
/// [LinePrefix] is a value type. It overloads [hashCode] and [==] and it's
/// critical that those be correct and efficient. These objects are used as
/// keys in the [LineSplitter]'s memoization table.
class LinePrefix {
  /// The number of chunks in the prefix.
  ///
  /// The suffix is the remaining chunks starting at index [length].
  final int length;

  /// The [Rule]s that apply to chunks in the prefix and have thus already had
  /// their values selected.
  ///
  /// Does not include rules that do not also appear in the suffix since they
  /// don't affect the suffix.
  final Map<Rule, int> ruleValues;

  /// The number of characters of "statement-based" indentation of the line
  /// after the prefix.
  ///
  /// This handles things like control flow, switch cases, and constructor
  /// initialization lists that tweak the per-line indentation.
  ///
  /// For nested blocks, this also includes the indentation to push the entire
  /// block over.
  final int _indent;

  final NestingSplitter _nesting;

  /// The absolute starting column of the line after this chunk.
  ///
  /// This takes into account whether the line should be flush left or not.
  int get column => _flushLeft ? 0 : _indent + _nesting.indent;
  final bool _flushLeft;

  /// Creates a new zero-length prefix with initial [indent] whose suffix is
  /// the entire line.
  LinePrefix(int indent, {bool flushLeft})
      : this._(0, {}, indent, new NestingSplitter(), flushLeft: flushLeft);

  LinePrefix._(this.length, this.ruleValues, this._indent, this._nesting,
      {bool flushLeft: false})
      : _flushLeft = flushLeft;

  bool operator ==(other) {
    if (other is! LinePrefix) return false;

    if (length != other.length) return false;
    if (_indent != other._indent) return false;
    if (_flushLeft != other._flushLeft) return false;
    if (_nesting != other._nesting) return false;

    // Compare rule values.
    if (ruleValues.length != other.ruleValues.length) return false;

    for (var key in ruleValues.keys) {
      if (other.ruleValues[key] != ruleValues[key]) return false;
    }

    return true;
  }

  int get hashCode => length.hashCode ^ _indent ^ _nesting.hashCode;

  /// Create a new LinePrefix one chunk longer than this one using [ruleValues],
  /// and assuming that we do not split before that chunk.
  LinePrefix extend(Map<Rule, int> ruleValues) =>
      new LinePrefix._(length + 1, ruleValues, _indent, _nesting,
          flushLeft: _flushLeft);

  /// Create a series of new LinePrefixes one chunk longer than this one using
  /// [ruleValues], and assuming that the new [chunk] splits at an expression
  /// boundary so there may be multiple possible different nesting stacks.
  ///
  /// If this prefix is for a nested block, [blockIndentation] may be nonzero
  /// to push the output to the right.
  Iterable<LinePrefix> split(
      Chunk chunk, int blockIndentation, Map<Rule, int> ruleValues) {
    var indent = chunk.indent + blockIndentation;
    var flushLeft = chunk.flushLeft;

    // If the chunk has a block, then its flushLeft property is for the first
    // line of the block, not the line after the block. The line after the block
    // is never flush left since it will always be for a `}` or `]`.
    if (chunk.blockChunks.isNotEmpty) flushLeft = false;

    return _nesting.update(chunk.nesting).map((nesting) => new LinePrefix._(
        length + 1, ruleValues, indent, nesting,
        flushLeft: flushLeft));
  }

  String toString() {
    var result = "prefix $length";
    if (_indent != 0) result += " indent ${_indent}";
    if (_nesting.indent != 0) result += " nesting ${_nesting.indent}";
    if (ruleValues.isNotEmpty) {
      var rules =
          ruleValues.keys.map((key) => "$key:${ruleValues[key]}").join(" ");

      result += " rules $rules";
    }
    return result;
  }
}
