// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef VERIBLE_COMMON_FORMATTING_STATE_NODE_H_
#define VERIBLE_COMMON_FORMATTING_STATE_NODE_H_

#include <cstddef>
#include <iosfwd>
#include <iterator>
#include <memory>
#include <stack>
#include <vector>

#include "common/formatting/basic_format_style.h"
#include "common/formatting/format_token.h"
#include "common/formatting/unwrapped_line.h"
#include "common/util/container_iterator_range.h"

namespace verible {

// A StateNode is used to keep a formatting state as the tokens of an
// UnwrappedLine are searched left to right.  Each StateNode represents one
// formatting decision: wrap or not-wrap.  Each StateNode maintains a pointer
// to its parent state, which is used for backtracking once a solution
// is reached.  StateNode is language-agnostic.
// StateNode is purely an implementation detail of line_wrap_searcher.cc.
struct StateNode {
  using path_type = std::vector<PreFormatToken>;
  using range_type = container_iterator_range<path_type::const_iterator>;

  // The StateNode that has an edge to this StateNode, to backtrack once a final
  // state is reached.
  std::shared_ptr<const StateNode> prev_state;

  // Iterator range marking the unexplored decisions beyond the current token.
  // TODO(fangism): make the iterator type a template parameter.  Might help
  // with mocking and testing.
  range_type undecided_path;

  // Explores one of the SpacingDecision choices.
  SpacingDecision spacing_choice = SpacingDecision::kPreserve;

  // The current column position, this increases with every token that is
  // appended onto the current line, and resets to the indentation level
  // (plus wrapping) with every line break.
  int current_column = 0;

  // The total cost along this decision path.  This monotonically increases
  // with each decision explored.
  int cumulative_cost = 0;

  // Kludge: in the event of a wrapped multi-line token, the current_column
  // position and the raw token text length are insufficient to infer what
  // the spaces before the format token are because current_column is only
  // based on the substring of text after the last newline.  To be able to
  // reconstruct the pre-format-token spacing, we must record it.
  // This is initialized with a sentinel value of -1 as a safety precaution
  // to guard against accidental use.
  int wrap_multiline_token_spaces_before = -1;

  // Keeps track of column positions of every level of wrapping, as determined
  // by balanced group delimiters such as braces, brackets, parentheses.
  // These column positions correspond to either the current indentation level
  // plus wrapping or the column position of the nearest group-opening
  // delimiter.
  // TODO(b/135730018): re-implement to minimize copying of stacks.
  // For example, use pointer or iterator to previous stack update.
  std::stack<int> wrap_column_positions;

  // Constructor for the root node of the search path, with no parent.
  // This automatically places the first token at the beginning of a new line
  // for position tracking purposes.
  // If the UnwrappedLine has only one token or is empty, the initial state
  // will be Done().
  StateNode(const UnwrappedLine &uwline, const BasicFormatStyle &style);

  // Constructor for nodes that represent new wrap decision trees to explore.
  // 'spacing_choice' reflects the decision being explored, e.g. append, wrap,
  // preserve.
  StateNode(const std::shared_ptr<const StateNode> &parent,
            const BasicFormatStyle &style, SpacingDecision spacing_choice);

  // Returns true when the undecided_path is empty.
  // The search is over when there are no more decisions to explore.
  bool Done() const { return undecided_path.begin() == undecided_path.end(); }

  // Returns a reference to the token that is being acted upon in this state.
  const PreFormatToken &GetCurrentToken() const {
    // The undecided_path always starts at the position after the current token.
    return *(undecided_path.begin() - 1);
  }

  // Returns a reference to the token that considered for wrapping vs.
  // appending.
  const PreFormatToken &GetNextToken() const {
    // The undecided_path always starts at the position after the current token.
    return *undecided_path.begin();
  }

  // Returns pointer to previous state before this decision node.
  // This functions as a forward-iterator going up the state ancestry chain.
  const StateNode *next() const { return prev_state.get(); }

  // Returns true if this state was initialized with an unwrapped line and
  // has no parent state.
  bool IsRootState() const { return prev_state == nullptr; }

  // Returns the total number of nodes in state ancestry, including itself.
  // This occurs in O(N) time, and is only suitable for testing/debug.
  size_t Depth() const {
    size_t depth = 1;
    const auto *iter = this;
    while (!iter->IsRootState()) {
      ++depth;
      iter = iter->prev_state.get();
    }
    return depth;
  }

  // Produce next state by appending a token if the result stays under the
  // column limit, or breaking onto a new line if required.
  static std::shared_ptr<const StateNode> AppendIfItFits(
      const std::shared_ptr<const StateNode> &current_state,
      const BasicFormatStyle &style);

  // Repeatedly apply AppendIfItFits() until Done() with formatting.
  // TODO(b/134711965): We may want a variant that preserves spaces too.
  static std::shared_ptr<const StateNode> QuickFinish(
      const std::shared_ptr<const StateNode> &current_state,
      const BasicFormatStyle &style);

  // Comparator provides an ordering of which paths should be explored
  // when maintained in a priority queue.  For Dijsktra-style algorithms,
  // we want to explore the min-cost paths first.
  bool operator<(const StateNode &r) const {
    return cumulative_cost < r.cumulative_cost ||
           // TODO(b/145558510): Favor solutions that use fewer lines.
           // To do that would require counting number of wrap decisions,
           // which is slow, unless we keep track of that number in StateNode.

           // tie-breaker: All else being equal, use terminal column position.
           (cumulative_cost == r.cumulative_cost &&
            current_column < r.current_column);
  }

  // Applies decisions from a path search to the set of format tokens in a
  // FormattedExcerpt.  'this' is the last decision in a tree that encodes
  // wrap decisions (through ancestry chain: prev_state) all the way back to
  // the first token in the original UnwrappedLine (that was used to
  // initialize the root state).
  void ReconstructFormatDecisions(FormattedExcerpt *) const;

 private:
  const PreFormatToken &GetPreviousToken() const;

  int UpdateColumnPosition();
  void UpdateCumulativeCost(const BasicFormatStyle &, int column_for_penalty);
  void OpenGroupBalance(const BasicFormatStyle &);
  void CloseGroupBalance();
};

// Human-readable representation for debugging only.
std::ostream &operator<<(std::ostream &, const StateNode &);

}  // namespace verible

#endif  // VERIBLE_COMMON_FORMATTING_STATE_NODE_H_
