// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gn/command_format.h"

#include <stddef.h>

#include <sstream>

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
#include "base/macros.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "gn/commands.h"
#include "gn/filesystem_utils.h"
#include "gn/input_file.h"
#include "gn/parser.h"
#include "gn/scheduler.h"
#include "gn/setup.h"
#include "gn/source_file.h"
#include "gn/string_utils.h"
#include "gn/switches.h"
#include "gn/tokenizer.h"

namespace commands {

const char kSwitchDryRun[] = "dry-run";
const char kSwitchDumpTree[] = "dump-tree";
const char kSwitchDumpTreeText[] = "text";
const char kSwitchDumpTreeJSON[] = "json";
const char kSwitchStdin[] = "stdin";

const char kFormat[] = "format";
const char kFormat_HelpShort[] = "format: Format .gn files.";
const char kFormat_Help[] =
    R"(gn format [--dump-tree] (--stdin | <list of build_files...>)

  Formats .gn file to a standard format.

  The contents of some lists ('sources', 'deps', etc.) will be sorted to a
  canonical order. To suppress this, you can add a comment of the form "#
  NOSORT" immediately preceding the assignment. e.g.

  # NOSORT
  sources = [
    "z.cc",
    "a.cc",
  ]

Arguments

  --dry-run
      Does not change or output anything, but sets the process exit code based
      on whether output would be different than what's on disk. This is useful
      for presubmit/lint-type checks.
      - Exit code 0: successful format, matches on disk.
      - Exit code 1: general failure (parse error, etc.)
      - Exit code 2: successful format, but differs from on disk.

  --dump-tree[=( text | json )]
      Dumps the parse tree to stdout and does not update the file or print
      formatted output. If no format is specified, text format will be used.

  --stdin
      Read input from stdin and write to stdout rather than update a file
      in-place.

Examples
  gn format //some/BUILD.gn //some/other/BUILD.gn //and/another/BUILD.gn
  gn format some\\BUILD.gn
  gn format /abspath/some/BUILD.gn
  gn format --stdin
)";

namespace {

const int kIndentSize = 2;
const int kMaximumWidth = 80;

const int kPenaltyLineBreak = 500;
const int kPenaltyHorizontalSeparation = 100;
const int kPenaltyExcess = 10000;
const int kPenaltyBrokenLineOnOneLiner = 5000;

enum Precedence {
  kPrecedenceLowest,
  kPrecedenceAssign,
  kPrecedenceOr,
  kPrecedenceAnd,
  kPrecedenceCompare,
  kPrecedenceAdd,
  kPrecedenceUnary,
  kPrecedenceSuffix,
};

int CountLines(const std::string& str) {
  return static_cast<int>(base::SplitStringPiece(str, "\n",
                                                 base::KEEP_WHITESPACE,
                                                 base::SPLIT_WANT_ALL)
                              .size());
}

class Printer {
 public:
  Printer();
  ~Printer();

  void Block(const ParseNode* file);

  std::string String() const { return output_; }

 private:
  // Format a list of values using the given style.
  enum SequenceStyle {
    kSequenceStyleList,
    kSequenceStyleBracedBlock,
    kSequenceStyleBracedBlockAlreadyOpen,
  };

  struct Metrics {
    Metrics() : first_length(-1), longest_length(-1), multiline(false) {}
    int first_length;
    int longest_length;
    bool multiline;
  };

  // Add to output.
  void Print(std::string_view str);

  // Add the current margin (as spaces) to the output.
  void PrintMargin();

  void TrimAndPrintToken(const Token& token);

  // End the current line, flushing end of line comments.
  void Newline();

  // Remove trailing spaces from the current line.
  void Trim();

  // Whether there's a blank separator line at the current position.
  bool HaveBlankLine();

  // Sort a list on the RHS if the LHS is 'sources', 'deps' or 'public_deps'.
  // The 'sources' are sorted alphabetically while the 'deps' and 'public_deps'
  // are sorted putting first the relative targets and then the global ones
  // (both sorted alphabetically).
  void SortIfSourcesOrDeps(const BinaryOpNode* binop);

  // Sort contiguous import() function calls in the given ordered list of
  // statements (the body of a block or scope).
  template <class PARSENODE>
  void SortImports(std::vector<std::unique_ptr<PARSENODE>>& statements);

  // Heuristics to decide if there should be a blank line added between two
  // items. For various "small" items, it doesn't look nice if there's too much
  // vertical whitespace added.
  bool ShouldAddBlankLineInBetween(const ParseNode* a, const ParseNode* b);

  // Get the 0-based x position on the current line.
  int CurrentColumn() const;

  // Get the current line in the output;
  int CurrentLine() const;

  // Adds an opening ( if prec is less than the outers (to maintain evalution
  // order for a subexpression). If an opening paren is emitted, *parenthesized
  // will be set so it can be closed at the end of the expression.
  void AddParen(int prec, int outer_prec, bool* parenthesized);

  // Print the expression to the output buffer. Returns the type of element
  // added to the output. The value of outer_prec gives the precedence of the
  // operator outside this Expr. If that operator binds tighter than root's,
  // Expr must introduce parentheses.
  int Expr(const ParseNode* root, int outer_prec, const std::string& suffix);

  // Generic penalties for exceeding maximum width, adding more lines, etc.
  int AssessPenalty(const std::string& output);

  // Tests if any lines exceed the maximum width.
  bool ExceedsMaximumWidth(const std::string& output);

  // Format a list of values using the given style.
  // |end| holds any trailing comments to be printed just before the closing
  // bracket.
  template <class PARSENODE>  // Just for const covariance.
  void Sequence(SequenceStyle style,
                const std::vector<std::unique_ptr<PARSENODE>>& list,
                const ParseNode* end,
                bool force_multiline);

  // Returns the penalty.
  int FunctionCall(const FunctionCallNode* func_call,
                   const std::string& suffix);

  // Create a clone of this Printer in a similar state (other than the output,
  // but including margins, etc.) to be used for dry run measurements.
  void InitializeSub(Printer* sub);

  template <class PARSENODE>
  bool ListWillBeMultiline(const std::vector<std::unique_ptr<PARSENODE>>& list,
                           const ParseNode* end);

  std::string output_;           // Output buffer.
  std::vector<Token> comments_;  // Pending end-of-line comments.
  int margin() const { return stack_.back().margin; }

  int penalty_depth_;
  int GetPenaltyForLineBreak() const {
    return penalty_depth_ * kPenaltyLineBreak;
  }

  struct IndentState {
    IndentState()
        : margin(0),
          continuation_requires_indent(false),
          parent_is_boolean_or(false) {}
    IndentState(int margin,
                bool continuation_requires_indent,
                bool parent_is_boolean_or)
        : margin(margin),
          continuation_requires_indent(continuation_requires_indent),
          parent_is_boolean_or(parent_is_boolean_or) {}

    // The left margin (number of spaces).
    int margin;

    bool continuation_requires_indent;

    bool parent_is_boolean_or;
  };
  // Stack used to track
  std::vector<IndentState> stack_;

  // Gives the precedence for operators in a BinaryOpNode.
  std::map<std::string_view, Precedence> precedence_;

  DISALLOW_COPY_AND_ASSIGN(Printer);
};

Printer::Printer() : penalty_depth_(0) {
  output_.reserve(100 << 10);
  precedence_["="] = kPrecedenceAssign;
  precedence_["+="] = kPrecedenceAssign;
  precedence_["-="] = kPrecedenceAssign;
  precedence_["||"] = kPrecedenceOr;
  precedence_["&&"] = kPrecedenceAnd;
  precedence_["<"] = kPrecedenceCompare;
  precedence_[">"] = kPrecedenceCompare;
  precedence_["=="] = kPrecedenceCompare;
  precedence_["!="] = kPrecedenceCompare;
  precedence_["<="] = kPrecedenceCompare;
  precedence_[">="] = kPrecedenceCompare;
  precedence_["+"] = kPrecedenceAdd;
  precedence_["-"] = kPrecedenceAdd;
  precedence_["!"] = kPrecedenceUnary;
  stack_.push_back(IndentState());
}

Printer::~Printer() = default;

void Printer::Print(std::string_view str) {
  output_.append(str);
}

void Printer::PrintMargin() {
  output_ += std::string(margin(), ' ');
}

void Printer::TrimAndPrintToken(const Token& token) {
  std::string trimmed;
  TrimWhitespaceASCII(std::string(token.value()), base::TRIM_ALL, &trimmed);
  Print(trimmed);
}

void Printer::Newline() {
  if (!comments_.empty()) {
    Print("  ");
    // Save the margin, and temporarily set it to where the first comment
    // starts so that multiple suffix comments are vertically aligned. This
    // will need to be fancier once we enforce 80 col.
    stack_.push_back(IndentState(CurrentColumn(), false, false));
    int i = 0;
    for (const auto& c : comments_) {
      if (i > 0) {
        Trim();
        Print("\n");
        PrintMargin();
      }
      TrimAndPrintToken(c);
      ++i;
    }
    stack_.pop_back();
    comments_.clear();
  }
  Trim();
  Print("\n");
  PrintMargin();
}

void Printer::Trim() {
  size_t n = output_.size();
  while (n > 0 && output_[n - 1] == ' ')
    --n;
  output_.resize(n);
}

bool Printer::HaveBlankLine() {
  size_t n = output_.size();
  while (n > 0 && output_[n - 1] == ' ')
    --n;
  return n > 2 && output_[n - 1] == '\n' && output_[n - 2] == '\n';
}

void Printer::SortIfSourcesOrDeps(const BinaryOpNode* binop) {
  if (const Comments* comments = binop->comments()) {
    const std::vector<Token>& before = comments->before();
    if (!before.empty() && (before.front().value() == "# NOSORT" ||
                            before.back().value() == "# NOSORT")) {
      // Allow disabling of sort for specific actions that might be
      // order-sensitive.
      return;
    }
  }
  const IdentifierNode* ident = binop->left()->AsIdentifier();
  const ListNode* list = binop->right()->AsList();
  if ((binop->op().value() == "=" || binop->op().value() == "+=" ||
       binop->op().value() == "-=") &&
      ident && list) {
    const std::string_view lhs = ident->value().value();
    if (base::EndsWith(lhs, "sources", base::CompareCase::SENSITIVE) ||
        lhs == "public")
      const_cast<ListNode*>(list)->SortAsStringsList();
    else if (base::EndsWith(lhs, "deps", base::CompareCase::SENSITIVE))
      const_cast<ListNode*>(list)->SortAsDepsList();
  }
}

template <class PARSENODE>
void Printer::SortImports(std::vector<std::unique_ptr<PARSENODE>>& statements) {
  // Build a set of ranges by indices of FunctionCallNode's that are imports.

  std::vector<std::vector<size_t>> import_statements;

  auto is_import = [](const PARSENODE* p) {
    const FunctionCallNode* func_call = p->AsFunctionCall();
    return func_call && func_call->function().value() == "import";
  };

  std::vector<size_t> current_group;
  for (size_t i = 0; i < statements.size(); ++i) {
    if (is_import(statements[i].get())) {
      if (i > 0 && (!is_import(statements[i - 1].get()) ||
                    ShouldAddBlankLineInBetween(statements[i - 1].get(),
                                                statements[i].get()))) {
        if (!current_group.empty()) {
          import_statements.push_back(current_group);
          current_group.clear();
        }
      }
      current_group.push_back(i);
    }
  }

  if (!current_group.empty())
    import_statements.push_back(current_group);

  struct CompareByImportFile {
    bool operator()(const std::unique_ptr<PARSENODE>& a,
                    const std::unique_ptr<PARSENODE>& b) const {
      const auto& a_args = a->AsFunctionCall()->args()->contents();
      const auto& b_args = b->AsFunctionCall()->args()->contents();
      std::string_view a_name;
      std::string_view b_name;
      if (!a_args.empty())
        a_name = a_args[0]->AsLiteral()->value().value();
      if (!b_args.empty())
        b_name = b_args[0]->AsLiteral()->value().value();

      auto is_absolute = [](std::string_view import) {
        return import.size() >= 3 && import[0] == '"' && import[1] == '/' &&
               import[2] == '/';
      };
      int a_is_rel = !is_absolute(a_name);
      int b_is_rel = !is_absolute(b_name);

      return std::tie(a_is_rel, a_name) < std::tie(b_is_rel, b_name);
    }
  };

  int line_after_previous = -1;

  for (const auto& group : import_statements) {
    size_t begin = group[0];
    size_t end = group.back() + 1;

    // Save the original line number so that ranges can be re-assigned. They're
    // contiguous because of the partitioning code above. Later formatting
    // relies on correct line number to know whether to insert blank lines,
    // which is why these need to be fixed up. Additionally, to handle multiple
    // imports on one line, they're assigned sequential line numbers, and
    // subsequent blocks will be gapped from them.
    int start_line =
        std::max(statements[begin]->GetRange().begin().line_number(),
                 line_after_previous + 1);

    std::sort(statements.begin() + begin, statements.begin() + end,
              CompareByImportFile());

    const PARSENODE* prev = nullptr;
    for (size_t i = begin; i < end; ++i) {
      const PARSENODE* node = statements[i].get();
      int line_number =
          prev ? prev->GetRange().end().line_number() + 1 : start_line;
      if (node->comments() && !node->comments()->before().empty())
        line_number++;
      const_cast<FunctionCallNode*>(node->AsFunctionCall())
          ->SetNewLocation(line_number);
      prev = node;
      line_after_previous = line_number + 1;
    }
  }
}

bool Printer::ShouldAddBlankLineInBetween(const ParseNode* a,
                                          const ParseNode* b) {
  LocationRange a_range = a->GetRange();
  LocationRange b_range = b->GetRange();
  // If they're already separated by 1 or more lines, then we want to keep a
  // blank line.
  return (b_range.begin().line_number() > a_range.end().line_number() + 1) ||
         // Always put a blank line before a block comment.
         b->AsBlockComment();
}

int Printer::CurrentColumn() const {
  int n = 0;
  while (n < static_cast<int>(output_.size()) &&
         output_[output_.size() - 1 - n] != '\n') {
    ++n;
  }
  return n;
}

int Printer::CurrentLine() const {
  int count = 1;
  for (const char* p = output_.c_str(); (p = strchr(p, '\n')) != nullptr;) {
    ++count;
    ++p;
  }
  return count;
}

void Printer::Block(const ParseNode* root) {
  const BlockNode* block = root->AsBlock();

  if (block->comments()) {
    for (const auto& c : block->comments()->before()) {
      TrimAndPrintToken(c);
      Newline();
    }
  }

  SortImports(const_cast<std::vector<std::unique_ptr<ParseNode>>&>(
      block->statements()));

  size_t i = 0;
  for (const auto& stmt : block->statements()) {
    Expr(stmt.get(), kPrecedenceLowest, std::string());
    Newline();
    if (stmt->comments()) {
      // Why are before() not printed here too? before() are handled inside
      // Expr(), as are suffix() which are queued to the next Newline().
      // However, because it's a general expression handler, it doesn't insert
      // the newline itself, which only happens between block statements. So,
      // the after are handled explicitly here.
      for (const auto& c : stmt->comments()->after()) {
        TrimAndPrintToken(c);
        Newline();
      }
    }
    if (i < block->statements().size() - 1 &&
        (ShouldAddBlankLineInBetween(block->statements()[i].get(),
                                     block->statements()[i + 1].get()))) {
      Newline();
    }
    ++i;
  }

  if (block->comments()) {
    if (!block->statements().empty() &&
        block->statements().back()->AsBlockComment()) {
      // If the block ends in a comment, and there's a comment following it,
      // then the two comments were originally separate, so keep them that way.
      Newline();
    }
    for (const auto& c : block->comments()->after()) {
      TrimAndPrintToken(c);
      Newline();
    }
  }
}

int Printer::AssessPenalty(const std::string& output) {
  int penalty = 0;
  std::vector<std::string> lines = base::SplitString(
      output, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  penalty += static_cast<int>(lines.size() - 1) * GetPenaltyForLineBreak();
  for (const auto& line : lines) {
    if (line.size() > kMaximumWidth)
      penalty += static_cast<int>(line.size() - kMaximumWidth) * kPenaltyExcess;
  }
  return penalty;
}

bool Printer::ExceedsMaximumWidth(const std::string& output) {
  for (const auto& line : base::SplitString(output, "\n", base::KEEP_WHITESPACE,
                                            base::SPLIT_WANT_ALL)) {
    if (line.size() > kMaximumWidth)
      return true;
  }
  return false;
}

void Printer::AddParen(int prec, int outer_prec, bool* parenthesized) {
  if (prec < outer_prec) {
    Print("(");
    *parenthesized = true;
  }
}

int Printer::Expr(const ParseNode* root,
                  int outer_prec,
                  const std::string& suffix) {
  std::string at_end = suffix;
  int penalty = 0;
  penalty_depth_++;

  if (root->comments()) {
    if (!root->comments()->before().empty()) {
      Trim();
      // If there's already other text on the line, start a new line.
      if (CurrentColumn() > 0)
        Print("\n");
      // We're printing a line comment, so we need to be at the current margin.
      PrintMargin();
      for (const auto& c : root->comments()->before()) {
        TrimAndPrintToken(c);
        Newline();
      }
    }
  }

  bool parenthesized = false;

  if (const AccessorNode* accessor = root->AsAccessor()) {
    AddParen(kPrecedenceSuffix, outer_prec, &parenthesized);
    Print(accessor->base().value());
    if (accessor->member()) {
      Print(".");
      Expr(accessor->member(), kPrecedenceLowest, std::string());
    } else {
      CHECK(accessor->index());
      Print("[");
      Expr(accessor->index(), kPrecedenceLowest, "]");
    }
  } else if (const BinaryOpNode* binop = root->AsBinaryOp()) {
    CHECK(precedence_.find(binop->op().value()) != precedence_.end());

    SortIfSourcesOrDeps(binop);

    Precedence prec = precedence_[binop->op().value()];

    // Since binary operators format left-to-right, it is ok for the left side
    // use the same operator without parentheses, so the left uses prec. For the
    // same reason, the right side cannot reuse the same operator, or else "x +
    // (y + z)" would format as "x + y + z" which means "(x + y) + z". So, treat
    // the right expression as appearing one precedence level higher.
    // However, because the source parens are not in the parse tree, as a
    // special case for && and || we insert strictly-redundant-but-helpful-for-
    // human-readers parentheses.
    int prec_left = prec;
    int prec_right = prec + 1;
    if (binop->op().value() == "&&" && stack_.back().parent_is_boolean_or) {
      Print("(");
      parenthesized = true;
    } else {
      AddParen(prec_left, outer_prec, &parenthesized);
    }

    int start_line = CurrentLine();
    int start_column = CurrentColumn();
    bool is_assignment = binop->op().value() == "=" ||
                         binop->op().value() == "+=" ||
                         binop->op().value() == "-=";

    int indent_column = start_column;
    if (is_assignment) {
      // Default to a double-indent for wrapped assignments.
      indent_column = margin() + kIndentSize * 2;

      // A special case for the long lists and scope assignments that are
      // common in .gn files, don't indent them + 4, even though they're just
      // continuations when they're simple lists like "x = [ a, b, c, ... ]" or
      // scopes like "x = { a = 1 b = 2 }". Put back to "normal" indenting.
      if (const ListNode* right_as_list = binop->right()->AsList()) {
        if (ListWillBeMultiline(right_as_list->contents(),
                                right_as_list->End()))
          indent_column = start_column;
      } else {
        if (binop->right()->AsBlock())
          indent_column = start_column;
      }
    }
    if (stack_.back().continuation_requires_indent)
      indent_column += kIndentSize * 2;

    stack_.push_back(IndentState(indent_column,
                                 stack_.back().continuation_requires_indent,
                                 binop->op().value() == "||"));
    Printer sub_left;
    InitializeSub(&sub_left);
    sub_left.Expr(binop->left(), prec_left,
                  std::string(" ") + std::string(binop->op().value()));
    bool left_is_multiline = CountLines(sub_left.String()) > 1;
    // Avoid walking the whole left redundantly times (see timing of Format.046)
    // so pull the output and comments from subprinter.
    Print(sub_left.String().substr(start_column));
    std::copy(sub_left.comments_.begin(), sub_left.comments_.end(),
              std::back_inserter(comments_));

    // Single line.
    Printer sub1;
    InitializeSub(&sub1);
    sub1.Print(" ");
    int penalty_current_line =
        sub1.Expr(binop->right(), prec_right, std::string());
    sub1.Print(suffix);
    penalty_current_line += AssessPenalty(sub1.String());
    if (!is_assignment && left_is_multiline) {
      // In e.g. xxx + yyy, if xxx is already multiline, then we want a penalty
      // for trying to continue as if this were one line.
      penalty_current_line +=
          (CountLines(sub1.String()) - 1) * kPenaltyBrokenLineOnOneLiner;
    }

    // Break after operator.
    Printer sub2;
    InitializeSub(&sub2);
    sub2.Newline();
    int penalty_next_line =
        sub2.Expr(binop->right(), prec_right, std::string());
    sub2.Print(suffix);
    penalty_next_line += AssessPenalty(sub2.String());

    // Force a list on the RHS that would normally be a single line into
    // multiline.
    bool tried_rhs_multiline = false;
    Printer sub3;
    InitializeSub(&sub3);
    int penalty_multiline_rhs_list = std::numeric_limits<int>::max();
    const ListNode* rhs_list = binop->right()->AsList();
    if (is_assignment && rhs_list &&
        !ListWillBeMultiline(rhs_list->contents(), rhs_list->End())) {
      sub3.Print(" ");
      sub3.stack_.push_back(IndentState(start_column, false, false));
      sub3.Sequence(kSequenceStyleList, rhs_list->contents(), rhs_list->End(),
                    true);
      sub3.stack_.pop_back();
      penalty_multiline_rhs_list = AssessPenalty(sub3.String());
      tried_rhs_multiline = true;
    }

    // If in all cases it was forced past 80col, then we don't break to avoid
    // breaking after '=' in the case of:
    //   variable = "... very long string ..."
    // as breaking and indenting doesn't make things much more readable, even
    // though there's fewer characters past the maximum width.
    bool exceeds_maximum_all_ways =
        ExceedsMaximumWidth(sub1.String()) &&
        ExceedsMaximumWidth(sub2.String()) &&
        (!tried_rhs_multiline || ExceedsMaximumWidth(sub3.String()));

    if (penalty_current_line < penalty_next_line || exceeds_maximum_all_ways) {
      Print(" ");
      Expr(binop->right(), prec_right, std::string());
    } else if (tried_rhs_multiline &&
               penalty_multiline_rhs_list < penalty_next_line) {
      // Force a multiline list on the right.
      Print(" ");
      stack_.push_back(IndentState(start_column, false, false));
      Sequence(kSequenceStyleList, rhs_list->contents(), rhs_list->End(), true);
      stack_.pop_back();
    } else {
      // Otherwise, put first argument and op, and indent next.
      Newline();
      penalty += std::abs(CurrentColumn() - start_column) *
                 kPenaltyHorizontalSeparation;
      Expr(binop->right(), prec_right, std::string());
    }
    stack_.pop_back();
    penalty += (CurrentLine() - start_line) * GetPenaltyForLineBreak();
  } else if (const BlockNode* block = root->AsBlock()) {
    Sequence(kSequenceStyleBracedBlock, block->statements(), block->End(),
             false);
  } else if (const ConditionNode* condition = root->AsConditionNode()) {
    Print("if (");
    Expr(condition->condition(), kPrecedenceLowest, ") {");
    Sequence(kSequenceStyleBracedBlockAlreadyOpen,
             condition->if_true()->statements(), condition->if_true()->End(),
             false);
    if (condition->if_false()) {
      Print(" else ");
      // If it's a block it's a bare 'else', otherwise it's an 'else if'. See
      // ConditionNode::Execute.
      bool is_else_if = condition->if_false()->AsBlock() == nullptr;
      if (is_else_if) {
        Expr(condition->if_false(), kPrecedenceLowest, std::string());
      } else {
        Sequence(kSequenceStyleBracedBlock,
                 condition->if_false()->AsBlock()->statements(),
                 condition->if_false()->AsBlock()->End(), false);
      }
    }
  } else if (const FunctionCallNode* func_call = root->AsFunctionCall()) {
    penalty += FunctionCall(func_call, at_end);
    at_end = "";
  } else if (const IdentifierNode* identifier = root->AsIdentifier()) {
    Print(identifier->value().value());
  } else if (const ListNode* list = root->AsList()) {
    Sequence(kSequenceStyleList, list->contents(), list->End(),
             /*force_multiline=*/false);
  } else if (const LiteralNode* literal = root->AsLiteral()) {
    Print(literal->value().value());
  } else if (const UnaryOpNode* unaryop = root->AsUnaryOp()) {
    Print(unaryop->op().value());
    Expr(unaryop->operand(), kPrecedenceUnary, std::string());
  } else if (const BlockCommentNode* block_comment = root->AsBlockComment()) {
    Print(block_comment->comment().value());
  } else if (const EndNode* end = root->AsEnd()) {
    Print(end->value().value());
  } else {
    CHECK(false) << "Unhandled case in Expr.";
  }

  if (parenthesized)
    Print(")");

  // Defer any end of line comment until we reach the newline.
  if (root->comments() && !root->comments()->suffix().empty()) {
    std::copy(root->comments()->suffix().begin(),
              root->comments()->suffix().end(), std::back_inserter(comments_));
  }

  Print(at_end);

  penalty_depth_--;
  return penalty;
}

template <class PARSENODE>
void Printer::Sequence(SequenceStyle style,
                       const std::vector<std::unique_ptr<PARSENODE>>& list,
                       const ParseNode* end,
                       bool force_multiline) {
  if (style == kSequenceStyleList) {
    Print("[");
  } else if (style == kSequenceStyleBracedBlock) {
    Print("{");
  } else if (style == kSequenceStyleBracedBlockAlreadyOpen) {
    style = kSequenceStyleBracedBlock;
  }

  if (style == kSequenceStyleBracedBlock) {
    force_multiline = true;
    SortImports(const_cast<std::vector<std::unique_ptr<PARSENODE>>&>(list));
  }

  force_multiline |= ListWillBeMultiline(list, end);

  if (list.size() == 0 && !force_multiline) {
    // No elements, and not forcing newlines, print nothing.
  } else if (list.size() == 1 && !force_multiline) {
    Print(" ");
    Expr(list[0].get(), kPrecedenceLowest, std::string());
    CHECK(!list[0]->comments() || list[0]->comments()->after().empty());
    Print(" ");
  } else {
    stack_.push_back(IndentState(margin() + kIndentSize,
                                 style == kSequenceStyleList, false));
    size_t i = 0;
    for (const auto& x : list) {
      Newline();
      // If:
      // - we're going to output some comments, and;
      // - we haven't just started this multiline list, and;
      // - there isn't already a blank line here;
      // Then: insert one.
      if (i != 0 && x->comments() && !x->comments()->before().empty() &&
          !HaveBlankLine()) {
        Newline();
      }
      bool body_of_list = i < list.size() - 1 || style == kSequenceStyleList;
      bool want_comma =
          body_of_list && (style == kSequenceStyleList && !x->AsBlockComment());
      Expr(x.get(), kPrecedenceLowest, want_comma ? "," : std::string());
      CHECK(!x->comments() || x->comments()->after().empty());
      if (body_of_list) {
        if (i < list.size() - 1 &&
            ShouldAddBlankLineInBetween(list[i].get(), list[i + 1].get()))
          Newline();
      }
      ++i;
    }

    // Trailing comments.
    if (end->comments() && !end->comments()->before().empty()) {
      if (list.size() >= 2)
        Newline();
      for (const auto& c : end->comments()->before()) {
        Newline();
        TrimAndPrintToken(c);
      }
    }

    stack_.pop_back();
    Newline();

    // Defer any end of line comment until we reach the newline.
    if (end->comments() && !end->comments()->suffix().empty()) {
      std::copy(end->comments()->suffix().begin(),
                end->comments()->suffix().end(), std::back_inserter(comments_));
    }
  }

  if (style == kSequenceStyleList)
    Print("]");
  else if (style == kSequenceStyleBracedBlock)
    Print("}");
}

int Printer::FunctionCall(const FunctionCallNode* func_call,
                          const std::string& suffix) {
  int start_line = CurrentLine();
  int start_column = CurrentColumn();
  Print(func_call->function().value());
  Print("(");

  bool have_block = func_call->block() != nullptr;
  bool force_multiline = false;

  const auto& list = func_call->args()->contents();
  const ParseNode* end = func_call->args()->End();

  if (end->comments() && !end->comments()->before().empty())
    force_multiline = true;

  // If there's before line comments, make sure we have a place to put them.
  for (const auto& i : list) {
    if (i->comments() && !i->comments()->before().empty())
      force_multiline = true;
  }

  // Calculate the penalties for 3 possible layouts:
  // 1. all on same line;
  // 2. starting on same line, broken at each comma but paren aligned;
  // 3. broken to next line + 4, broken at each comma.
  std::string terminator = ")";
  if (have_block)
    terminator += " {";
  terminator += suffix;

  // Special case to make function calls of one arg taking a long list of
  // boolean operators not indent.
  bool continuation_requires_indent =
      list.size() != 1 || !list[0]->AsBinaryOp();

  // 1: Same line.
  Printer sub1;
  InitializeSub(&sub1);
  sub1.stack_.push_back(
      IndentState(CurrentColumn(), continuation_requires_indent, false));
  int penalty_one_line = 0;
  for (size_t i = 0; i < list.size(); ++i) {
    penalty_one_line += sub1.Expr(list[i].get(), kPrecedenceLowest,
                                  i < list.size() - 1 ? ", " : std::string());
  }
  sub1.Print(terminator);
  penalty_one_line += AssessPenalty(sub1.String());
  // This extra penalty prevents a short second argument from being squeezed in
  // after a first argument that went multiline (and instead preferring a
  // variant below).
  penalty_one_line +=
      (CountLines(sub1.String()) - 1) * kPenaltyBrokenLineOnOneLiner;

  // 2: Starting on same line, broken at commas.
  Printer sub2;
  InitializeSub(&sub2);
  sub2.stack_.push_back(
      IndentState(CurrentColumn(), continuation_requires_indent, false));
  int penalty_multiline_start_same_line = 0;
  for (size_t i = 0; i < list.size(); ++i) {
    penalty_multiline_start_same_line +=
        sub2.Expr(list[i].get(), kPrecedenceLowest,
                  i < list.size() - 1 ? "," : std::string());
    if (i < list.size() - 1) {
      sub2.Newline();
    }
  }
  sub2.Print(terminator);
  penalty_multiline_start_same_line += AssessPenalty(sub2.String());

  // 3: Starting on next line, broken at commas.
  Printer sub3;
  InitializeSub(&sub3);
  sub3.stack_.push_back(IndentState(margin() + kIndentSize * 2,
                                    continuation_requires_indent, false));
  sub3.Newline();
  int penalty_multiline_start_next_line = 0;
  for (size_t i = 0; i < list.size(); ++i) {
    if (i == 0) {
      penalty_multiline_start_next_line +=
          std::abs(sub3.CurrentColumn() - start_column) *
          kPenaltyHorizontalSeparation;
    }
    penalty_multiline_start_next_line +=
        sub3.Expr(list[i].get(), kPrecedenceLowest,
                  i < list.size() - 1 ? "," : std::string());
    if (i < list.size() - 1) {
      sub3.Newline();
    }
  }
  sub3.Print(terminator);
  penalty_multiline_start_next_line += AssessPenalty(sub3.String());

  int penalty = penalty_multiline_start_next_line;
  bool fits_on_current_line = false;
  if (penalty_one_line < penalty_multiline_start_next_line ||
      penalty_multiline_start_same_line < penalty_multiline_start_next_line) {
    fits_on_current_line = true;
    penalty = penalty_one_line;
    if (penalty_multiline_start_same_line < penalty_one_line) {
      penalty = penalty_multiline_start_same_line;
      force_multiline = true;
    }
  } else {
    force_multiline = true;
  }

  if (list.size() == 0 && !force_multiline) {
    // No elements, and not forcing newlines, print nothing.
  } else {
    if (penalty_multiline_start_next_line < penalty_multiline_start_same_line) {
      stack_.push_back(IndentState(margin() + kIndentSize * 2,
                                   continuation_requires_indent, false));
      Newline();
    } else {
      stack_.push_back(
          IndentState(CurrentColumn(), continuation_requires_indent, false));
    }

    for (size_t i = 0; i < list.size(); ++i) {
      const auto& x = list[i];
      if (i > 0) {
        if (fits_on_current_line && !force_multiline)
          Print(" ");
        else
          Newline();
      }
      bool want_comma = i < list.size() - 1 && !x->AsBlockComment();
      Expr(x.get(), kPrecedenceLowest, want_comma ? "," : std::string());
      CHECK(!x->comments() || x->comments()->after().empty());
      if (i < list.size() - 1) {
        if (!want_comma)
          Newline();
      }
    }

    // Trailing comments.
    if (end->comments() && !end->comments()->before().empty()) {
      if (!list.empty())
        Newline();
      for (const auto& c : end->comments()->before()) {
        Newline();
        TrimAndPrintToken(c);
      }
      Newline();
    }
    stack_.pop_back();
  }

  // Defer any end of line comment until we reach the newline.
  if (end->comments() && !end->comments()->suffix().empty()) {
    std::copy(end->comments()->suffix().begin(),
              end->comments()->suffix().end(), std::back_inserter(comments_));
  }

  Print(")");
  Print(suffix);

  if (have_block) {
    Print(" ");
    Sequence(kSequenceStyleBracedBlock, func_call->block()->statements(),
             func_call->block()->End(), false);
  }
  return penalty + (CurrentLine() - start_line) * GetPenaltyForLineBreak();
}

void Printer::InitializeSub(Printer* sub) {
  sub->stack_ = stack_;
  sub->comments_ = comments_;
  sub->penalty_depth_ = penalty_depth_;
  sub->Print(std::string(CurrentColumn(), 'x'));
}

template <class PARSENODE>
bool Printer::ListWillBeMultiline(
    const std::vector<std::unique_ptr<PARSENODE>>& list,
    const ParseNode* end) {
  if (list.size() > 1)
    return true;

  if (end && end->comments() && !end->comments()->before().empty())
    return true;

  // If there's before line comments, make sure we have a place to put them.
  for (const auto& i : list) {
    if (i->comments() && !i->comments()->before().empty())
      return true;
  }

  // When a scope is used as a list entry, it's too complicated to go one a
  // single line (the block will always be formatted multiline itself).
  if (list.size() >= 1 && list[0]->AsBlock())
    return true;

  return false;
}

void DoFormat(const ParseNode* root,
              TreeDumpMode dump_tree,
              std::string* output) {
  if (dump_tree == TreeDumpMode::kPlainText) {
    std::ostringstream os;
    RenderToText(root->GetJSONNode(), 0, os);
    fprintf(stderr, "%s", os.str().c_str());
  } else if (dump_tree == TreeDumpMode::kJSON) {
    std::string os;
    base::JSONWriter::WriteWithOptions(
        root->GetJSONNode(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &os);
    fprintf(stderr, "%s", os.c_str());
  }

  Printer pr;
  pr.Block(root);
  *output = pr.String();
}

}  // namespace

bool FormatStringToString(const std::string& input,
                          TreeDumpMode dump_tree,
                          std::string* output) {
  SourceFile source_file;
  InputFile file(source_file);
  file.SetContents(input);
  Err err;
  // Tokenize.
  std::vector<Token> tokens =
      Tokenizer::Tokenize(&file, &err, WhitespaceTransform::kInvalidToSpace);
  if (err.has_error()) {
    err.PrintToStdout();
    return false;
  }

  // Parse.
  std::unique_ptr<ParseNode> parse_node = Parser::Parse(tokens, &err);
  if (err.has_error()) {
    err.PrintToStdout();
    return false;
  }

  DoFormat(parse_node.get(), dump_tree, output);
  return true;
}

int RunFormat(const std::vector<std::string>& args) {
  bool dry_run =
      base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDryRun);
  TreeDumpMode dump_tree = TreeDumpMode::kInactive;
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDumpTree)) {
    std::string tree_type =
        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            kSwitchDumpTree);
    if (tree_type == kSwitchDumpTreeJSON) {
      dump_tree = TreeDumpMode::kJSON;
    } else if (tree_type.empty() || tree_type == kSwitchDumpTreeText) {
      dump_tree = TreeDumpMode::kPlainText;
    } else {
      Err(Location(), tree_type +
                          " is an invalid value for --dump-tree. Specify "
                          "\"" +
                          kSwitchDumpTreeText + "\" or \"" +
                          kSwitchDumpTreeJSON + "\".\n")
          .PrintToStdout();
      return 1;
    }
  }
  bool from_stdin =
      base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchStdin);

  if (dry_run) {
    // --dry-run only works with an actual file to compare to.
    from_stdin = false;
  }

  bool quiet =
      base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kQuiet);

  if (from_stdin) {
    if (args.size() != 0) {
      Err(Location(), "Expecting no arguments when reading from stdin.\n")
          .PrintToStdout();
      return 1;
    }
    std::string input = ReadStdin();
    std::string output;
    if (!FormatStringToString(input, dump_tree, &output))
      return 1;
    printf("%s", output.c_str());
    return 0;
  }

  if (args.size() == 0) {
    Err(Location(), "Expecting one or more arguments, see `gn help format`.\n")
        .PrintToStdout();
    return 1;
  }

  Setup setup;
  SourceDir source_dir =
      SourceDirForCurrentDirectory(setup.build_settings().root_path());

  // TODO(scottmg): Eventually, this list of files should be processed in
  // parallel.
  for (const auto& arg : args) {
    Err err;
    SourceFile file = source_dir.ResolveRelativeFile(Value(nullptr, arg), &err);
    if (err.has_error()) {
      err.PrintToStdout();
      return 1;
    }

    base::FilePath to_format = setup.build_settings().GetFullPath(file);
    std::string original_contents;
    if (!base::ReadFileToString(to_format, &original_contents)) {
      Err(Location(),
          std::string("Couldn't read \"") + FilePathToUTF8(to_format))
          .PrintToStdout();
      return 1;
    }

    std::string output_string;
    if (!FormatStringToString(original_contents, dump_tree, &output_string)) {
      return 1;
    }
    if (dump_tree == TreeDumpMode::kInactive) {
      // Update the file in-place.
      if (dry_run)
        return original_contents == output_string ? 0 : 2;
      if (original_contents != output_string) {
        if (base::WriteFile(to_format, output_string.data(),
                            static_cast<int>(output_string.size())) == -1) {
          Err(Location(),
              std::string("Failed to write formatted output back to \"") +
                  FilePathToUTF8(to_format) + std::string("\"."))
              .PrintToStdout();
          return 1;
        }
        if (!quiet) {
          printf("Wrote formatted to '%s'.\n",
                 FilePathToUTF8(to_format).c_str());
        }
      }
    }
  }

  return 0;
}

}  // namespace commands
