// Copyright (c) 2015, 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_splitting.solve_state_queue;

import 'line_splitter.dart';
import 'solve_state.dart';

/// A priority queue of [SolveStates] to consider while line splitting.
///
/// This is based on the [HeapPriorityQueue] class from the "collection"
/// package, but is modified to handle the "overlap" logic that allows one
/// [SolveState] to supercede another.
///
/// States are stored internally in a heap ordered by cost, the number of
/// overflow characters. When a new state is added to the heap, it will be
/// discarded, or a previously enqueued one will be discarded, if two overlap.
class SolveStateQueue {
  /// Initial capacity of a queue when created, or when added to after a [clear].
  /// Number can be any positive value. Picking a size that gives a whole
  /// number of "tree levels" in the heap is only done for aesthetic reasons.
  static const int _INITIAL_CAPACITY = 7;

  LineSplitter _splitter;

  /// List implementation of a heap.
  List<SolveState> _queue = new List<SolveState>(_INITIAL_CAPACITY);

  /// Number of elements in queue.
  /// The heap is implemented in the first [_length] entries of [_queue].
  int _length = 0;

  bool get isNotEmpty => _length != 0;

  void bindSplitter(LineSplitter splitter) {
    // Only do this once.
    assert(_splitter == null);

    _splitter = splitter;
  }

  /// Add [state] to the queue.
  ///
  /// Grows the capacity if the backing list is full.
  void add(SolveState state) {
    if (_tryOverlap(state)) return;

    if (_length == _queue.length) {
      var newCapacity = _queue.length * 2 + 1;
      if (newCapacity < _INITIAL_CAPACITY) newCapacity = _INITIAL_CAPACITY;

      var newQueue = new List<SolveState>(newCapacity);
      newQueue.setRange(0, _length, _queue);
      _queue = newQueue;
    }

    _bubbleUp(state, _length++);
  }

  SolveState removeFirst() {
    assert(_length > 0);

    // Remove the highest priority state.
    var result = _queue[0];
    _length--;

    // Fill the gap with the one at the end of the list and re-heapify.
    if (_length > 0) {
      var last = _queue[_length];
      _queue[_length] = null;
      _bubbleDown(last, 0);
    }

    return result;
  }

  /// Orders this state relative to [other].
  ///
  /// This is a best-first ordering that prefers cheaper states even if they
  /// overflow because this ensures it finds the best solution first as soon as
  /// it finds one that fits in the page so it can early out.
  int _compare(SolveState a, SolveState b) {
    // TODO(rnystrom): It may be worth sorting by the estimated lowest number
    // of overflow characters first. That doesn't help in cases where there is
    // a solution that fits, but may help in corner cases where there is no
    // fitting solution.

    var comparison = _compareScore(a, b);
    if (comparison != 0) return comparison;

    return _compareRules(a, b);
  }

  /// Compares the overflow and cost of [a] to [b].
  int _compareScore(SolveState a, SolveState b) {
    if (a.splits.cost != b.splits.cost) {
      return a.splits.cost.compareTo(b.splits.cost);
    }

    return a.overflowChars.compareTo(b.overflowChars);
  }

  /// Distinguish states based on the rule values just so that states with the
  /// same cost range but different rule values don't get considered identical
  /// and inadvertantly merged.
  int _compareRules(SolveState a, SolveState b) {
    for (var rule in _splitter.rules) {
      var aValue = a.getValue(rule);
      var bValue = b.getValue(rule);

      if (aValue != bValue) return aValue.compareTo(bValue);
    }

    // The way SolveStates are expanded should guarantee that we never generate
    // the exact same state twice. Getting here implies that that failed.
    throw "unreachable";
  }

  /// Determines if any already enqueued state overlaps [state].
  ///
  /// If so, chooses the best and discards the other. Returns `true` in this
  /// case. Otherwise, returns `false`.
  bool _tryOverlap(SolveState state) {
    if (_length == 0) return false;

    // Count positions from one instead of zero. This gives the numbers some
    // nice properties. For example, all right children are odd, their left
    // sibling is even, and the parent is found by shifting right by one.
    // Valid range for position is [1.._length], inclusive.
    var position = 1;

    // Pre-order depth first search, omit child nodes if the current node has
    // lower priority than [object], because all nodes lower in the heap will
    // also have lower priority.
    do {
      var index = position - 1;
      var enqueued = _queue[index];

      var comparison = _compareScore(enqueued, state);

      if (comparison == 0) {
        var overlap = enqueued.compareOverlap(state);
        if (overlap < 0) {
          // The old state is better, so just discard the new one.
          return true;
        } else if (overlap > 0) {
          // The new state is better than the enqueued one, so replace it.
          _queue[index] = state;
          return true;
        } else {
          // We can't merge them, so sort by their bound rule values.
          comparison = _compareRules(enqueued, state);
        }
      }

      if (comparison < 0) {
        // Element may be in subtree. Continue with the left child, if any.
        var leftChildPosition = position * 2;
        if (leftChildPosition <= _length) {
          position = leftChildPosition;
          continue;
        }
      }

      // Find the next right sibling or right ancestor sibling.
      do {
        while (position.isOdd) {
          // While position is a right child, go to the parent.
          position >>= 1;
        }

        // Then go to the right sibling of the left child.
        position += 1;
      } while (position > _length); // Happens if last element is a left child.
    } while (position != 1); // At root again. Happens for right-most element.

    return false;
  }

  /// Place [element] in heap at [index] or above.
  ///
  /// Put element into the empty cell at `index`. While the `element` has
  /// higher priority than the parent, swap it with the parent.
  void _bubbleUp(SolveState element, int index) {
    while (index > 0) {
      var parentIndex = (index - 1) ~/ 2;
      var parent = _queue[parentIndex];

      if (_compare(element, parent) > 0) break;

      _queue[index] = parent;
      index = parentIndex;
    }

    _queue[index] = element;
  }

  /// Place [element] in heap at [index] or above.
  ///
  /// Put element into the empty cell at `index`. While the `element` has lower
  /// priority than either child, swap it with the highest priority child.
  void _bubbleDown(SolveState element, int index) {
    var rightChildIndex = index * 2 + 2;

    while (rightChildIndex < _length) {
      var leftChildIndex = rightChildIndex - 1;
      var leftChild = _queue[leftChildIndex];
      var rightChild = _queue[rightChildIndex];

      var comparison = _compare(leftChild, rightChild);
      var minChildIndex;
      var minChild;

      if (comparison < 0) {
        minChild = leftChild;
        minChildIndex = leftChildIndex;
      } else {
        minChild = rightChild;
        minChildIndex = rightChildIndex;
      }

      comparison = _compare(element, minChild);

      if (comparison <= 0) {
        _queue[index] = element;
        return;
      }

      _queue[index] = minChild;
      index = minChildIndex;
      rightChildIndex = index * 2 + 2;
    }

    var leftChildIndex = rightChildIndex - 1;
    if (leftChildIndex < _length) {
      var child = _queue[leftChildIndex];
      var comparison = _compare(element, child);

      if (comparison > 0) {
        _queue[index] = child;
        index = leftChildIndex;
      }
    }

    _queue[index] = element;
  }
}
