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

#include "verilog/formatting/token_annotator.h"

#include <iterator>
#include <vector>

#include "absl/strings/string_view.h"
#include "common/formatting/format_token.h"
#include "common/formatting/tree_annotator.h"
#include "common/strings/range.h"
#include "common/text/syntax_tree_context.h"
#include "common/text/text_structure.h"
#include "common/text/token_info.h"
#include "common/util/iterator_range.h"
#include "common/util/logging.h"
#include "common/util/with_reason.h"
#include "verilog/CST/verilog_nonterminals.h"
#include "verilog/formatting/format_style.h"
#include "verilog/formatting/verilog_token.h"
#include "verilog/parser/verilog_parser.h"
#include "verilog/parser/verilog_token_classifications.h"
#include "verilog/parser/verilog_token_enum.h"

namespace verilog {
namespace formatter {

using ::verible::PreFormatToken;
using ::verible::SpacingOptions;
using ::verible::SyntaxTreeContext;
using ::verible::WithReason;
using FTT = FormatTokenType;

// Signal that spacing was not explicitly handled in case logic.
// This value must be negative.
static constexpr int kUnhandledSpacesRequired = -1;

static bool IsUnaryPrefixExpressionOperand(const PreFormatToken& left,
                                           const SyntaxTreeContext& context) {
  return (IsUnaryOperator(verilog_tokentype(left.TokenEnum())) &&
          context.IsInsideFirst({NodeEnum::kUnaryPrefixExpression},
                                {NodeEnum::kExpression})) ||
         // Treat '##' like a unary prefix operator.
         left.TokenEnum() == verilog_tokentype::TK_POUNDPOUND;
}

static bool IsInsideNumericLiteral(const PreFormatToken& left,
                                   const PreFormatToken& right) {
  return (left.format_token_enum == FormatTokenType::numeric_literal &&
          right.format_token_enum == FormatTokenType::numeric_base) ||
         left.format_token_enum == FormatTokenType::numeric_base;
}

// Returns true if keyword can be used like a function/method call.
// Based on various LRM sections mentioning subroutine calls.
static bool IsKeywordCallable(verilog_tokentype e) {
  switch (e) {
    case TK_and:  // array method
    case TK_find:
    case TK_find_index:
    case TK_find_first:
    case TK_find_first_index:
    case TK_find_last:
    case TK_find_last_index:
    case TK_min:
    case TK_max:
    case TK_new:
    case TK_or:  // array method
    case TK_product:
    case TK_randomize:
    case TK_reverse:
    case TK_rsort:
    case TK_shuffle:
    case TK_sort:
    case TK_sum:
    case TK_unique:  // array method
    case TK_xor:     // array method
      // TODO(fangism): Verilog-AMS functions, like sin, cos, ...
      return true;
    default:
      break;
  }
  return false;
}

// The following combinations cannot be merged without a space:
//   number number : would result in one different number
//   number id/kw : would result in a bad identifier (lexer)
//   id/kw number : would result in a (different) identifier
//   id/kw id/kw : would result in a (different) identifier
static bool PairwiseNonmergeable(const PreFormatToken& ftoken) {
  return ftoken.TokenEnum() == TK_DecNumber ||
         ftoken.format_token_enum == FormatTokenType::identifier ||
         ftoken.format_token_enum == FormatTokenType::keyword;
}

static bool InDeclaredDimensions(const SyntaxTreeContext& context) {
  return context.IsInsideFirst(
      {NodeEnum::kPackedDimensions, NodeEnum::kUnpackedDimensions}, {});
}

static bool InRangeLikeContext(const SyntaxTreeContext& context) {
  return context.IsInsideFirst(
      {NodeEnum::kDimensionScalar, NodeEnum::kDimensionRange,
       NodeEnum::kDimensionSlice, NodeEnum::kCycleDelayRange},
      {});
}

static bool IsAnySemicolon(const PreFormatToken& ftoken) {
  // These are just syntactically disambiguated versions of ';'.
  return ftoken.TokenEnum() == ';' ||
         ftoken.TokenEnum() ==
             verilog_tokentype::SemicolonEndOfAssertionVariableDeclarations;
}

// Returns minimum number of spaces required between left and right token.
// Returning kUnhandledSpacesRequired means the case was not explicitly
// handled, and it is up to the caller to decide what to do when this happens.
static WithReason<int> SpacesRequiredBetween(
    const PreFormatToken& left, const PreFormatToken& right,
    const SyntaxTreeContext& left_context,
    const SyntaxTreeContext& right_context, const FormatStyle& style) {
  VLOG(3) << "Spacing between " << verilog_symbol_name(left.TokenEnum())
          << " and " << verilog_symbol_name(right.TokenEnum());
  // Higher precedence rules should be handled earlier in this function.

  // Preserve space after escaped identifiers.
  if (left.TokenEnum() == EscapedIdentifier) {
    return {1, "Escaped identifiers must end with whitespace."};
  }

  if (right.TokenEnum() == verilog_tokentype::TK_LINE_CONT) {
    return {0, "Add no spaces before \\ line continuation."};
  }
  if (left.TokenEnum() == verilog_tokentype::TK_LINE_CONT) {
    return {0, "Add no spaces after \\ line continuation."};
  }

  if (IsComment(FormatTokenType(right.format_token_enum))) {
    return {2, "Style: require 2+ spaces before comments"};
    // TODO(fangism): Take this from FormatStyle.
  }

  if (left.format_token_enum == FormatTokenType::open_group ||
      right.format_token_enum == FormatTokenType::close_group) {
    return {0,
            "Prefer \"(foo)\" over \"( foo )\", \"[x]\" over \"[ x ]\", "
            "and \"{y}\" over \"{ y }\"."};
  }

  // For now, leave everything inside [dimensions] alone.
  if (InDeclaredDimensions(right_context)) {
    // ... except for the spacing before '[' and around ':',
    // which are covered elsewhere.
    if (right.TokenEnum() != '[' && left.TokenEnum() != ':' &&
        right.TokenEnum() != ':') {
      return {kUnhandledSpacesRequired,
              "Leave [expressions] inside scalar and range dimensions alone "
              "(for now)."};
    }
  }

  // Unary operators (context-sensitive)
  if (IsUnaryPrefixExpressionOperand(left, right_context) &&
      (left.format_token_enum != FormatTokenType::binary_operator ||
       !IsUnaryOperator(static_cast<verilog_tokentype>(right.TokenEnum())))) {
    // TODO: There are _some_ unary operators on the right that could
    // be formatted with 0-space, for example:
    // 'a = & ~b'; could be 'a = &~b;'
    return {0, "Bind unary prefix operator close to its operand."};
  }

  if (left.TokenEnum() == TK_SCOPE_RES) {
    return {0, "Prefer \"::id\" over \":: id\", \"::*\" over \":: *\""};
  }

  // Delimiters, list separators
  if (right.TokenEnum() == ',') return {0, "No space before comma"};
  if (left.TokenEnum() == ',') return {1, "Require space after comma"};

  if (IsAnySemicolon(right)) {
    if (left.TokenEnum() == ':') {
      return {1, "Space between semicolon and colon, (e.g. \"default: ;\")"};
    }
    return {0, "No space before semicolon"};
  }
  if (IsAnySemicolon(left)) {
    return {1, "Require space after semicolon"};
  }

  if (left.TokenEnum() == TK_return) {
    return {1, "Space between return keyword and return value"};
  }

  if (right_context.IsInsideFirst({NodeEnum::kStreamingConcatenation}, {})) {
    if (left.TokenEnum() == TK_LS || left.TokenEnum() == TK_RS) {
      return {0, "No space around streaming operators"};
    } else if (left.format_token_enum == FormatTokenType::numeric_literal ||
               left.format_token_enum == FormatTokenType::identifier ||
               left.format_token_enum == FormatTokenType::keyword) {
      return {0, "No space around streaming operator slice size"};
    }
  }

  // "@(" vs. "@ (" for event control
  // "@*" vs. "@ *" for event control, '*' is not a binary operator here
  if (left.TokenEnum() == '@') {
    return {0, "No space after \"@\" in most cases."};
  }
  if (right.TokenEnum() == '@') {
    return {1, "Space before \"@\" in most cases."};
  }

  // Do not force space between '^' and '{' operators
  if (right_context.IsInsideFirst({NodeEnum::kUnaryPrefixExpression}, {})) {
    if (IsUnaryOperator(static_cast<verilog_tokentype>(left.TokenEnum())) &&
        right.TokenEnum() == '{') {
      return {0, "No space between unary and concatenation operators"};
    }
  }

  // Add missing space around either side of all types of assignment operator.
  // "assign foo = bar;"  instead of "assign foo =bar;"
  // Consider assignment operators in the same class as binary operators.
  if (left.format_token_enum == FormatTokenType::binary_operator ||
      right.format_token_enum == FormatTokenType::binary_operator) {
    // Inside [], allows 0 or 1 spaces, and symmetrize.
    // TODO(fangism): make this behavior configurable
    if (right.format_token_enum == FormatTokenType::binary_operator &&
        InRangeLikeContext(right_context)) {
      if (style.compact_indexing_and_selections &&
          !InDeclaredDimensions(right_context)) {
        return {0,
                "Compact binary expressions inside indexing / bit selection "
                "operator []"};
      }

      int spaces = right.OriginalLeadingSpaces().length();
      if (spaces > 1) {
        spaces = 1;
      }
      return {spaces, "Limit <= 1 space before binary operator inside []."};
    }
    if (left.format_token_enum == FormatTokenType::binary_operator &&
        InRangeLikeContext(left_context)) {
      return {left.before.spaces_required,
              "Symmetrize spaces before and after binary operator inside []."};
    }
    return {1, "Space around binary and assignment operators"};
  }

  // If the token on either side is an empty string, do not inject any
  // additional spaces.  This can occur with some lexical tokens like
  // verilog_tokentype::PP_define_body.
  if (left.token->text().empty() || right.token->text().empty()) {
    return {0, "No additional space around empty-string tokens."};
  }

  // Remove any extra spaces between numeric literals' width, base and digits.
  // "16'h123, 'h123" instead of "16 'h123", "16'h 123, 'h 123"
  if (IsInsideNumericLiteral(left, right)) {
    return {0, "No space inside based numeric literals"};
  }

  if (right_context.IsInsideFirst(
          {NodeEnum::kUdpCombEntry, NodeEnum::kUdpSequenceEntry}, {})) {
    // Spacing before ';' is handled above
    return {1, "One space around UDP entries"};
  }

  // TODO(fangism): Never insert trailing spaces before a newline.

  // Hierarchy examples: "a.b", "a::b"
  if (left.format_token_enum == FormatTokenType::hierarchy ||
      right.format_token_enum == FormatTokenType::hierarchy)
    return {0,
            "No space separating hierarchy components "
            "(separated by . or ::)"};
  // TODO(fangism): space between numeric literals and '.'
  // Don't want to accidentally form m.d floating-point values.

  // cast operator, e.g. "void'(...)"
  if (right.TokenEnum() == '\'' || left.TokenEnum() == '\'') {
    return {0, "No space around cast operator '\\''"};
  }

  if (right.TokenEnum() == '(') {
    // "#(" vs. "# (" for parameter formals and arguments
    if (left.TokenEnum() == '#') return {0, "Fuse \"#(\""};

    // ") (" vs. ")(" for between parameter and port formals
    if (left.TokenEnum() == ')') {
      return {1, "Separate \") (\" between parameters and ports"};
    }

    // General handling of ID '(' spacing:
    if (left.format_token_enum == FormatTokenType::identifier ||
        IsKeywordCallable(verilog_tokentype(left.TokenEnum()))) {
      // TODO(fangism): This logic should use .DirectParentIs() to minimize risk
      // of unintended reach.
      if (right_context.IsInside(NodeEnum::kActualNamedPort) ||
          right_context.IsInside(NodeEnum::kPort)) {
        return {0, "Named port: no space between ID and '('"};
      }
      if (right_context.IsInside(NodeEnum::kGateInstance) ||
          right_context.IsInside(NodeEnum::kPrimitiveGateInstance)) {
        return {1, "Module/primitive instance: want space between ID and '('"};
      }
      if (left_context.DirectParentIs(NodeEnum::kModuleHeader)) {
        return {1,
                "Module/interface declarations: want space between ID and '('"};
      }
      // Default: This case intended to cover function/task/macro calls:
      return {0, "Function/constructor calls: no space before ("};
    }
  }

  if (left.TokenEnum() == ':') {
    // Spacing in ranges
    if (InRangeLikeContext(right_context)) {
      // Take advantage here that the left token was already annotated (above)
      return {left.before.spaces_required,
              "Symmetrize spaces before and after ':' in bit slice"};
    }
    // Most contexts want a space after ':'.
    return {1, "Default to 1 space after ':'"};
  }

  if (left.TokenEnum() == '}') {
    // e.g. typedef struct { ... } foo_t;
    return {1, "Space after '}' in most other cases."};
  }
  if (right.TokenEnum() == '{') {
    if (left.format_token_enum == FormatTokenType::keyword) {
      return {1, "Space between keyword and '{'."};
    }
    if (right_context.DirectParentsAre(
            {NodeEnum::kBraceGroup, NodeEnum::kConstraintDeclaration})) {
      return {1, "Space before '{' when opening a constraint definition body."};
    }
    if (right_context.DirectParentsAre(
            {NodeEnum::kBraceGroup, NodeEnum::kCoverPoint})) {
      return {1, "Space before '{' when opening a coverpoint body."};
    }
    if (right_context.DirectParentsAre(
            {NodeEnum::kBraceGroup, NodeEnum::kEnumType})) {
      return {1, "Space before '{' when opening an enum type."};
    }
    if (left.TokenEnum() == ')') {
      return {1, "Space betwen ')' and '{', e.g. conditional constraint."};
    }
    if (left.TokenEnum() == ']' && InDeclaredDimensions(left_context)) {
      return {1, "Space between declared array type and '{' (e.g. in typedef)"};
    }
    return {0, "No space before '{' in most other contexts."};
  }

  // Handle padding around packed array dimensions like "type [N] id;"
  if ((left.format_token_enum == FormatTokenType::keyword ||
       left.format_token_enum == FormatTokenType::identifier) &&
      right.TokenEnum() == '[') {
    if (right_context.IsInsideFirst({NodeEnum::kPackedDimensions},
                                    {NodeEnum::kExpression})) {
      // "type [packed...]" (space between type and packed dimensions)
      // avoid touching any expressions inside the packed dimensions
      return {1, "spacing before [packed dimensions] of declarations"};
    }
    // All other contexts, such as "a[i]" indices, no space.
    return {0, "All other cases of \".*[\", no space"};
  }
  if (left.TokenEnum() == ']' &&
      right.format_token_enum == FormatTokenType::identifier) {
    if (right_context.DirectParentsAre(
            {NodeEnum::kUnqualifiedId,
             NodeEnum::kDataTypeImplicitBasicIdDimensions})) {
      // "[packed...] id" (space between packed dimensions and id)
      return {1, "spacing after [packed dimensions] of declarations"};
    }
    // Not sure if "] id" appears in any other context, so leave it unhandled.
  }

  // Cannot merge tokens that would result in a different token.
  if (PairwiseNonmergeable(left) && PairwiseNonmergeable(right)) {
    return {1, "Cannot pair {number, identifier, keyword} without space."};
  }

  if (right.TokenEnum() == ':') {
    if (left.TokenEnum() == TK_default) {
      return {0, "No space inside \"default:\""};
    }
    if (right_context.DirectParentIsOneOf(
            {NodeEnum::kCaseItem, NodeEnum::kCaseInsideItem,
             NodeEnum::kCasePatternItem, NodeEnum::kGenerateCaseItem,
             NodeEnum::kPropertyCaseItem, NodeEnum::kRandSequenceCaseItem,
             NodeEnum::kCoverPoint})) {
      return {0, "Case-like items, no space before ':'"};
    }

    // Everything that resembles an end-label should have 1 space
    //   example nodes: kLabel, kEndNew, kFunctionEndLabel
    if (IsEndKeyword(verilog_tokentype(left.TokenEnum()))) {
      return {1, "Want 1 space between end-keyword and ':'"};
    }

    // Spacing between 'begin' and ':' is already covered
    // Spacing between 'fork' and ':' is already covered

    // Everything that resembles a prefix-statement label,
    // and label before 'begin'
    if (right_context.DirectParentIsOneOf({NodeEnum::kBlockIdentifier,
                                           NodeEnum::kLabeledStatement,
                                           NodeEnum::kGenerateBlock})) {
      return {1, "1 space before ':' in prefix block labels"};
    }

    // kConditionExpression should have 1 space
    if (right_context.DirectParentIs(NodeEnum::kConditionExpression)) {
      return {1, "condition ?: expression wants 1 space around ':'"};
    }

    // Spacing in ranges
    if (InRangeLikeContext(right_context)) {
      int spaces = right.OriginalLeadingSpaces().length();
      if (spaces > 1) {
        spaces = 1;
      }
      return {spaces, "Limit spaces before ':' in bit slice to 0 or 1"};
    }
    if (right_context.DirectParentIs(NodeEnum::kValueRange)) {
      return {1, "Spaces around ':' in value ranges."};
    }

    // TODO(fangism): Everything that resembles a range (in index, dimensions)
    // should have 1 space.
    //   kValueRange, kCycleRange
    //   kMinTypMax expressions?

    // TODO(fangism): Other unknowns:
    //   'enum_name' in verilog.y
    //   kMemberPattern?
    //   kPatternExpression?
    //   ':' as a polarity operator?
    //   as a UDP combinational entry? UDP sequence entry?
    //   kBindDirective?
    //   kCoverCross? kCoverPoint?
    //   kProduction? (randsequence)

    // For now, if case is not explicitly handled, preserve existing space.
  }

  // "if (...)", "for (...) instead of "if(...)", "for(...)",
  // "case ...", "return ..."
  if (left.format_token_enum == FormatTokenType::keyword) {
    // TODO(b/144605476): function-like keywords, however, do not get a space.
    return {1, "Space between flow control keywords and ("};
  }

  if (left.TokenEnum() == verilog_tokentype::TK_TimeLiteral) {
    if (right.TokenEnum() == ';') {
      return {0, "No space between time literal and ';'."};
    }
    return {1, "Space after time literals in most other cases."};
  }

  if (right.TokenEnum() == TK_POUNDPOUND)
    return {1, "Space before ## (delay) operator"};
  if (left.format_token_enum == FormatTokenType::unary_operator)
    return {0, "++i over ++ i"};  // "++i" instead of "++ i"
  if (right.format_token_enum == FormatTokenType::unary_operator)
    return {0, "i++ over i ++"};  // "i++" instead of "i ++"

  // TODO(fangism): handle ranges [ ... : ... ]

  if (left.TokenEnum() == TK_DecNumber &&
      right.TokenEnum() == TK_UnBasedNumber) {
    // e.g. 1'b1, 16'hbabe
    return {0, "No space between numeric width and un-based number"};
  }

  // Brackets in multi-dimensional arrays/indices.
  if (left.TokenEnum() == ']' && right.TokenEnum() == '[') {
    return {0, "No spaces separating multidimensional arrays/indices"};
  }

  if (left.TokenEnum() == '#') {
    return {0, "No spaces after # (delay expressions, parameters)."};
  }
  if (right.TokenEnum() == '#') {
    // This may be controversial or context-dependent, as parameterized
    // classes often appear with method calls like:
    //   type#(params...)::method(...);
    if (left_context.DirectParentIs(NodeEnum::kUnqualifiedId) &&
        !left_context.IsInsideFirst(
            {NodeEnum::kInstantiationType, NodeEnum::kBindTargetInstance,
             NodeEnum::kExtendsList},
            {})) {
      return {0, "No space before # when direct parent is kUnqualifiedId."};
    } else {
      return {1, "Spaces before # in most other contexts."};
    }
  }

  if (right.format_token_enum == FormatTokenType::keyword) {
    return {1, "Space before keywords in most other cases."};
  }

  // e.g. always_ff @(posedge clk) begin ...
  // e.g. case (expr): ...
  if (left.TokenEnum() == ')') {
    switch (right.TokenEnum()) {
      case ':':
        return {0, "No space between ')' and ':'."};
      default:
        break;
    }
    return {1, "Space between ')' and most other tokens"};
  }
  if (left.TokenEnum() == verilog_tokentype::MacroCallCloseToEndLine) {
    if (IsAnySemicolon(right)) {
      return {0, "No space between macro-closing ')' and ';'"};
    }
    // Really only expect comments to follow macro-closing ')'
    return {1, "Space between macro-closing ')' and most other tokens"};
  }
  if (left.TokenEnum() == ']') {
    return {1, "Space between ']' and most other tokens"};
  }

  if (IsPreprocessorKeyword(
          static_cast<verilog_tokentype>(right.TokenEnum()))) {
    // most of these should start on their own line anyway
    return {1, "Preprocessor keywords should be separated from token on left."};
  }

  if (IsComment(FormatTokenType(left.format_token_enum))) {
    // Nothing should ever be to the right of an EOL comment.
    // But we have to explicitly handle these cases to prevent them from
    // unintentionally preserving spacing after comments.
    return {1, "Handle left=comment to avoid preserving unwanted spaces."};
  }

  // Case was not explicitly handled.
  return {kUnhandledSpacesRequired, "Default: spacing not explicitly handled"};
}

struct SpacePolicy {
  int spaces_required;
  bool force_preserve_spaces;
};

static SpacePolicy SpacesRequiredBetween(
    const FormatStyle& style, const PreFormatToken& left,
    const PreFormatToken& right, const SyntaxTreeContext& left_context,
    const SyntaxTreeContext& right_context) {
  // Default for unhandled cases, 1 space to be conservative.
  constexpr int kUnhandledSpacesDefault = 1;
  const auto spaces =
      SpacesRequiredBetween(left, right, left_context, right_context, style);
  VLOG(1) << "spaces: " << spaces.value << ", reason: " << spaces.reason;

  if (spaces.value == kUnhandledSpacesRequired) {
    VLOG(1) << "Unhandled inter-token spacing between "
            << verilog_symbol_name(left.TokenEnum()) << " and "
            << verilog_symbol_name(right.TokenEnum()) << ", defaulting to "
            << kUnhandledSpacesDefault;
    return SpacePolicy{kUnhandledSpacesDefault, true};
  }
  // else spacing was explicitly handled in a case
  return SpacePolicy{spaces.value, false};
}

// Context-independent break penalty factor.
static WithReason<int> BreakPenaltyBetweenTokens(
    const verible::PreFormatToken& left, const verible::PreFormatToken& right) {
  // Higher precedence rules should be handled earlier in this function.
  if (left.format_token_enum == FormatTokenType::identifier &&
      right.format_token_enum == FormatTokenType::open_group) {
    return {20, "identifier, open-group"};
  }
  // Hierarchy examples: "a.b", "a::b"
  // TODO(fangism): '.' is not always hierarchy, differentiate by context.
  // slightly prefer to break on the left: "a .b" better than "a. b"
  if (left.format_token_enum == FormatTokenType::hierarchy)
    return {50, "hierarchy separator on left"};
  if (right.format_token_enum == FormatTokenType::hierarchy)
    return {45, "hierarchy separator on right"};

  // Prefer to split after commas rather than before them.
  if (right.TokenEnum() == ',') return {10, "avoid breaking before ','"};
  if (right.TokenEnum() == ';') return {10, "avoid breaking before ';'"};

  if (left.TokenEnum() == ',') return {-5, "encourage breaking after ','"};
  if (left.TokenEnum() == ';') return {-5, "encourage breaking after ';'"};

  // Prefer to split after an assignment operator, rather than before.
  // TODO(fangism): use context to cover all assignment-like cases
  if (right.TokenEnum() == '=') return {8, "right is '='"};

  if ((left.format_token_enum != FormatTokenType::binary_operator ||
       left.TokenEnum() == '=') &&
      right.format_token_enum == FormatTokenType::open_group) {
    // Prefer to keep '(' with a token on the left, as long as it is not binary
    // operator other than '='
    // TODO(fangism): ... except when () is used as precedence.
    return {5, "right is open-group"};
  }
  // Prefer to keep ')' with whatever is on the left.
  if (right.format_token_enum == FormatTokenType::close_group ||
      right.TokenEnum() == verilog_tokentype::MacroCallCloseToEndLine)
    return {10, "right is close-group"};

  if (left.TokenEnum() == TK_DecNumber &&
      right.TokenEnum() == TK_UnBasedNumber) {
    // e.g. 1'b1, 16'hbabe
    // doesn't really matter, because we never break here
    return {90, "numeric width, base"};
  }

  return {0, "no further adjustment (default)"};
}

static int CommonAncestors(const SyntaxTreeContext& left,
                           const SyntaxTreeContext& right) {
  // TODO(fangism): re-check of common ancestry is slow (linear-time),
  // and could be avoided by memoizing the point of common ancestry between
  // leaves *during* the traversal.
  const auto* shorter = &left;
  const auto* longer = &right;
  // For C++11 compatibility, we use the 3-iterator form of std::mismatch().
  if (shorter->size() > longer->size()) std::swap(shorter, longer);
  const auto first_mismatches =
      std::mismatch(shorter->begin(), shorter->end(), longer->begin());
  const int short_common =
      std::distance(shorter->begin(), first_mismatches.first);
  const int long_common =
      std::distance(longer->begin(), first_mismatches.second);
  CHECK_GE(short_common, 0);
  CHECK_EQ(short_common, long_common);
  return short_common;
}

// Token-independent break penalty factor.
static int ContextBasedPenalty(const SyntaxTreeContext& left_context,
                               const SyntaxTreeContext& right_context) {
  // This factor takes into account syntax tree depth, favoring keeping
  // elements deeper in the tree closer together.
  // The current simple model gives equal weight to every element in the
  // context stack.
  // TODO(fangism): custom weights by syntax tree node type.
  constexpr int kDepthScaleFactor = 2;
  const int num_common = CommonAncestors(left_context, right_context);
  const int penalty = num_common * kDepthScaleFactor;
  return penalty;
}

static WithReason<int> TokensWithContextBreakPenalty(
    const verible::PreFormatToken& left, const verible::PreFormatToken& right,
    const SyntaxTreeContext& left_context,
    const SyntaxTreeContext& right_context) {
  const verilog_tokentype left_type =
      static_cast<verilog_tokentype>(left.TokenEnum());
  const verilog_tokentype right_type =
      static_cast<verilog_tokentype>(right.TokenEnum());
  if (right_context.DirectParentIs(NodeEnum::kConditionExpression) &&
      IsTernaryOperator(right_type)) {
    return {10, "Prefer to split after ternary operators (+10 on left)."};
  }
  if (left_context.DirectParentIs(NodeEnum::kConditionExpression) &&
      IsTernaryOperator(left_type)) {
    return {-5, "Prefer to split after ternary operators (-5 on right)."};
  }
  if (right_context.DirectParentIs(NodeEnum::kBinaryExpression) &&
      right.format_token_enum == FormatTokenType::binary_operator) {
    // This value should be kept small so that binding affinity still honors
    // operator precedence which is currently reflected in syntax tree depth.
    return {8, "Prefer to split after binary operators (+8 on left)."};
  }
  if (left_context.DirectParentIs(NodeEnum::kBinaryExpression) &&
      left.format_token_enum == FormatTokenType::binary_operator) {
    return {-5, "Prefer to split after binary operators (-5 on right)."};
  }
  return {0, "No adjustment."};
}

// Returns the split penalty for line-breaking before the right token.
static WithReason<int> BreakPenaltyBetween(
    const verible::PreFormatToken& left, const verible::PreFormatToken& right,
    const SyntaxTreeContext& left_context,
    const SyntaxTreeContext& right_context) {
  VLOG(3) << "Inter-token penalty between "
          << verilog_symbol_name(left.TokenEnum()) << " and "
          << verilog_symbol_name(right.TokenEnum());

  const int depth_penalty = ContextBasedPenalty(left_context, right_context);
  VLOG(3) << "context break penalty: " << depth_penalty;

  // This factor only looks at left and right tokens:
  const auto inter_token_penalty = BreakPenaltyBetweenTokens(left, right);
  VLOG(3) << "inter-token break penalty: " << inter_token_penalty.value << ", "
          << inter_token_penalty.reason;

  const auto token_with_context_penalty =
      TokensWithContextBreakPenalty(left, right, left_context, right_context);
  VLOG(3) << "token+context break penalty: " << token_with_context_penalty.value
          << ", " << token_with_context_penalty.reason;

  constexpr int kMinPenalty = 1;   // absolute minimum
  constexpr int kPenaltyBias = 5;  // baseline penalty value
  const int total_penalty =
      std::max(kPenaltyBias + depth_penalty + inter_token_penalty.value +
                   token_with_context_penalty.value,
               kMinPenalty);

  VLOG(3) << "total break penalty: " << total_penalty;
  return {total_penalty, inter_token_penalty.reason};
}

// Returns decision whether to break, not break, or evaluate both choices.
static WithReason<SpacingOptions> BreakDecisionBetween(
    const FormatStyle& style, const PreFormatToken& left,
    const PreFormatToken& right, const SyntaxTreeContext& left_context,
    const SyntaxTreeContext& right_context) {
  // For now, leave everything inside [dimensions] alone.
  if (InDeclaredDimensions(right_context)) {
    // ... except for the spacing immediately around '[' and ']',
    // which is covered by other rules.
    if (left.TokenEnum() != '[' && left.TokenEnum() != ']' &&
        right.TokenEnum() != '[' && right.TokenEnum() != ']' &&
        left.TokenEnum() != ':' && right.TokenEnum() != ':') {
      return {SpacingOptions::Preserve,
              "For now, leave spaces inside [] untouched."};
    }
  }

  if (right.TokenEnum() == verilog_tokentype::TK_LINE_CONT) {
    return {SpacingOptions::MustAppend,
            "Keep \\ line continuation attached to its left neighbor."};
  }

  if (left.TokenEnum() == verilog_tokentype::TK_LINE_CONT) {
    return {SpacingOptions::MustWrap,
            "Keep \\ line continuation is always followed by \\n."};
  }

  if (left.TokenEnum() == PP_define) {
    return {SpacingOptions::MustAppend,
            "Keep `define and macro name together."};
  }
  if (right.TokenEnum() == PP_define_body) {
    // TODO(b/141517267): reflow macro definition text with flexible
    // line-continuations.
    const absl::string_view text = right.Text();
    if (std::count(text.begin(), text.end(), '\n') >= 2) {
      return {SpacingOptions::Preserve,
              "Preserve spacing before a multi-line macro definition body."};
    } else {
      return {SpacingOptions::MustAppend,
              "Macro definition body must start on same line (but may be "
              "line-continued)."};
    }
  }

  // Check for mandatory line breaks.
  if (left.format_token_enum == FTT::eol_comment ||
      left.TokenEnum() == PP_define_body  // definition excludes trailing '\n'
  ) {
    return {SpacingOptions::MustWrap, "Token must be newline-terminated"};
  }

  if (right.format_token_enum == FTT::eol_comment) {
    // Check if there are any newlines between these tokens' texts.
    // Caution: when testing this case, must provide valid text between
    // tokens to avoid reading uninitialized memory.
    auto preceding_whitespace = verible::make_string_view_range(
        left.token->text().end(), right.token->text().begin());

    auto pos = preceding_whitespace.find_first_of('\n', 0);
    if (pos == absl::string_view::npos) {
      // There are other tokens on this line
      return {SpacingOptions::MustAppend,
              "EOL comment cannot break from "
              "tokens to the left on its line"};
    }
  }

  if (left.format_token_enum == FTT::comment_block ||
      right.format_token_enum == FTT::comment_block) {
    auto preceding_whitespace = verible::make_string_view_range(
        left.token->text().end(), right.token->text().begin());

    auto pos = preceding_whitespace.find_first_of('\n', 0);
    if (pos != absl::string_view::npos) {
      // TODO(mglb): Preserve would be more suitable, but it doesn't work
      // correctly yet.
      // Add support for "Preserve" in Layout Optimizer.
      // Correctly split partitions before tokens with "Preserve" decision in
      // Tree Unwrapper.
      return {SpacingOptions::MustWrap,
              "Force-preserve line break around block comment"};
    }
  }

  // TODO(fangism): check for all token types in verilog.lex that
  // scan to an end-of-line, even if it returns the newline to scanning with
  // yyless().

  // Unary operators (context-sensitive)
  // For now, never separate unary prefix operators from their operands.
  if (IsUnaryPrefixExpressionOperand(left, right_context)) {
    return {SpacingOptions::MustAppend,
            "Never separate unary prefix operator from its operand"};
  }

  if (IsInsideNumericLiteral(left, right)) {
    return {SpacingOptions::MustAppend,
            "Never separate numeric width, base, and digits"};
  }

  // Preprocessor macro definitions with args: no space between ID and '('.
  if (left.TokenEnum() == PP_Identifier && right.TokenEnum() == '(') {
    return {SpacingOptions::MustAppend, "No space between macro call id and ("};
  }

  // TODO(fangism): No break between `define and PP_Identifier.

  if (IsEndKeyword(verilog_tokentype(right.TokenEnum()))) {
    return {SpacingOptions::MustWrap, "end* keywords should start own lines"};
  }

  if (right.TokenEnum() == TK_else) {
    // TODO(fangism): feels like this should be the responsibility of
    // tree_unwrapper, handled by kElseClause, kGenerateElseClause, etc.
    if (left.TokenEnum() == TK_end)
      return {SpacingOptions::MustAppend,
              "'end'-'else' and should be together on one line."};
    if (left.TokenEnum() == '}')
      return {SpacingOptions::MustAppend,
              "'}'-'else' and should be together on one line."};
    // TODO(fangism): Some styles prefer to start with 'else' on its own line.
    return {SpacingOptions::MustWrap, "'else' starts its own line."};
  }

  if ((left.TokenEnum() == TK_else) && (right.TokenEnum() == TK_begin)) {
    return {SpacingOptions::MustAppend,
            "'else'-'begin' tokens should be together on one line."};
  }

  if ((left.TokenEnum() == ')') && (right.TokenEnum() == TK_begin)) {
    return {SpacingOptions::MustAppend,
            "')'-'begin' tokens should be together on one line."};
  }

  if (left.TokenEnum() == verilog_tokentype::MacroCallCloseToEndLine) {
    if (!IsComment(FormatTokenType(right.format_token_enum)) &&
        !IsAnySemicolon(right)) {
      return {SpacingOptions::MustWrap,
              "Macro-closing ')' should end its own line except for comments "
              "nad ';'."};
    }
  }

  if (left.TokenEnum() == PP_else || left.TokenEnum() == PP_endif) {
    if (IsComment(FormatTokenType(right.format_token_enum))) {
      return {SpacingOptions::Undecided, "Comment may follow `else and `end"};
    }
    return {SpacingOptions::MustWrap,
            "`end and `else should be on their own line except for comments."};
  }

  if (IsPreprocessorKeyword(
          static_cast<verilog_tokentype>(right.TokenEnum()))) {
    // The tree unwrapper should make sure these start their own partition.
    return {SpacingOptions::MustWrap,
            "Preprocessor directives should start their own line."};
  }

  if (left.TokenEnum() == '#') {
    return {SpacingOptions::MustAppend,
            "Never separate # from whatever follows (delay expressions)."};
  }
  if (left.TokenEnum() == verilog_tokentype::TK_TimeLiteral) {
    if (right.TokenEnum() == ';') {
      return {SpacingOptions::MustAppend,
              "Keep delay statements together, like \"#1ps;\"."};
    }
  }

  if (left.TokenEnum() == ',' &&
      right.TokenEnum() == verilog_tokentype::MacroArg) {
    const absl::string_view text(right.Text());
    if (std::find(text.begin(), text.end(), '\n') != text.end()) {
      return {SpacingOptions::MustWrap,
              "Multi-line unlexed macro arguments start on their own line."};
    }
  }

  // By default, leave undecided for penalty minimization.
  return {SpacingOptions::Undecided,
          "Default: leave wrap decision to algorithm"};
}

// Extern linkage for sake of direct testing, though not exposed in public
// headers.
// TODO(fangism): could move this to a -internal.h header.
void AnnotateFormatToken(const FormatStyle& style,
                         const PreFormatToken& prev_token,
                         PreFormatToken* curr_token,
                         const SyntaxTreeContext& prev_context,
                         const SyntaxTreeContext& curr_context) {
  const auto p = SpacesRequiredBetween(style, prev_token, *curr_token,
                                       prev_context, curr_context);
  curr_token->before.spaces_required = p.spaces_required;
  if (p.force_preserve_spaces) {
    // forego all inter-token calculations
    curr_token->before.break_decision = SpacingOptions::Preserve;
  } else {
    // Update the break penalty and if the curr_token is allowed to
    // break before it.
    const auto break_penalty = BreakPenaltyBetween(prev_token, *curr_token,
                                                   prev_context, curr_context);
    curr_token->before.break_penalty = break_penalty.value;
    const auto breaker = BreakDecisionBetween(style, prev_token, *curr_token,
                                              prev_context, curr_context);
    curr_token->before.break_decision = breaker.value;
    VLOG(3) << "line break constraint: " << breaker.value << ": "
            << breaker.reason;
  }
}

void AnnotateFormattingInformation(
    const FormatStyle& style, const verible::TextStructureView& text_structure,
    std::vector<verible::PreFormatToken>* format_tokens) {
  // This interface just forwards the relevant information from text_structure.
  AnnotateFormattingInformation(style, text_structure.Contents().begin(),
                                text_structure.SyntaxTree().get(),
                                text_structure.EOFToken(), format_tokens);
}

void AnnotateFormattingInformation(
    const FormatStyle& style, const char* buffer_start,
    const verible::Symbol* syntax_tree_root,
    const verible::TokenInfo& eof_token,
    std::vector<verible::PreFormatToken>* format_tokens) {
  if (format_tokens->empty()) {
    return;
  }

  if (buffer_start != nullptr) {
    // For unit testing, tokens' text snippets don't necessarily originate
    // from the same contiguous string buffer, so skip this step.
    ConnectPreFormatTokensPreservedSpaceStarts(buffer_start, format_tokens);
  }

  // Annotate inter-token information using the syntax tree for context.
  AnnotateFormatTokensUsingSyntaxContext(
      syntax_tree_root, eof_token, format_tokens->begin(), format_tokens->end(),
      // lambda: bind the FormatStyle, forwarding all other arguments
      [&style](const PreFormatToken& prev_token, PreFormatToken* curr_token,
               const SyntaxTreeContext& prev_context,
               const SyntaxTreeContext& current_context) {
        AnnotateFormatToken(style, prev_token, curr_token, prev_context,
                            current_context);
      });
}

}  // namespace formatter
}  // namespace verilog
