// Copyright 2017 The Bazel Authors. All Rights Reserved.
//
// 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.

package com.google.devtools.build.lib.syntax;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests the {@code toString} and pretty printing methods for {@link Node} subclasses. */
@RunWith(JUnit4.class)
public final class PrettyPrintTest {

  private static StarlarkFile parseFile(String... lines) throws SyntaxError.Exception {
    ParserInput input = ParserInput.fromLines(lines);
    StarlarkFile file = StarlarkFile.parse(input);
    if (!file.ok()) {
      throw new SyntaxError.Exception(file.errors());
    }
    return file;
  }

  private static Statement parseStatement(String... lines) throws SyntaxError.Exception {
    return parseFile(lines).getStatements().get(0);
  }

  private static Expression parseExpression(String... lines) throws SyntaxError.Exception {
    return Expression.parse(ParserInput.fromLines(lines));
  }

  private static String join(String... lines) {
    return Joiner.on("\n").join(lines);
  }

  /**
   * Asserts that the given node's pretty print at a given indent level matches the given string.
   */
  private static void assertPrettyMatches(Node node, int indentLevel, String expected) {
    StringBuilder buf = new StringBuilder();
    new NodePrinter(buf, indentLevel).printNode(node);
    assertThat(buf.toString()).isEqualTo(expected);
  }

  /** Asserts that the given node's pretty print with no indent matches the given string. */
  private static void assertPrettyMatches(Node node, String expected) {
    assertPrettyMatches(node, 0, expected);
  }

  /** Asserts that the given node's pretty print with one indent matches the given string. */
  private static void assertIndentedPrettyMatches(Node node, String expected) {
    assertPrettyMatches(node, 1, expected);
  }

  /** Asserts that the given node's {@code toString} matches the given string. */
  private static void assertTostringMatches(Node node, String expected) {
    assertThat(node.toString()).isEqualTo(expected);
  }

  /**
   * Parses the given string as an expression, and asserts that its pretty print matches the given
   * string.
   */
  private static void assertExprPrettyMatches(String source, String expected)
      throws SyntaxError.Exception {
      Expression node = parseExpression(source);
      assertPrettyMatches(node, expected);
  }

  /**
   * Parses the given string as an expression, and asserts that its {@code toString} matches the
   * given string.
   */
  private static void assertExprTostringMatches(String source, String expected)
      throws SyntaxError.Exception {
      Expression node = parseExpression(source);
      assertThat(node.toString()).isEqualTo(expected);
  }

  /**
   * Parses the given string as an expression, and asserts that both its pretty print and {@code
   * toString} return the original string.
   */
  private static void assertExprBothRoundTrip(String source) throws SyntaxError.Exception {
    assertExprPrettyMatches(source, source);
    assertExprTostringMatches(source, source);
  }

  /**
   * Parses the given string as a statement, and asserts that its pretty print with one indent
   * matches the given string.
   */
  private static void assertStmtIndentedPrettyMatches(String source, String expected)
      throws SyntaxError.Exception {
    Statement node = parseStatement(source);
    assertIndentedPrettyMatches(node, expected);
  }

  /**
   * Parses the given string as an statement, and asserts that its {@code toString} matches the
   * given string.
   */
  private static void assertStmtTostringMatches(String source, String expected)
      throws SyntaxError.Exception {
    Statement node = parseStatement(source);
    assertThat(node.toString()).isEqualTo(expected);
  }

  // Expressions.

  @Test
  public void abstractComprehension() throws SyntaxError.Exception {
    // Covers DictComprehension and ListComprehension.
    assertExprBothRoundTrip("[z for y in x if True for z in y]");
    assertExprBothRoundTrip("{z: x for y in x if True for z in y}");
  }

  @Test
  public void binaryOperatorExpression() throws SyntaxError.Exception {
    assertExprPrettyMatches("1 + 2", "(1 + 2)");
    assertExprTostringMatches("1 + 2", "1 + 2");

    assertExprPrettyMatches("1 + (2 * 3)", "(1 + (2 * 3))");
    assertExprTostringMatches("1 + (2 * 3)", "1 + 2 * 3");
  }

  @Test
  public void conditionalExpression() throws SyntaxError.Exception {
    assertExprBothRoundTrip("1 if True else 2");
  }

  @Test
  public void dictExpression() throws SyntaxError.Exception {
    assertExprBothRoundTrip("{1: \"a\", 2: \"b\"}");
  }

  @Test
  public void dotExpression() throws SyntaxError.Exception {
    assertExprBothRoundTrip("o.f");
  }

  @Test
  public void funcallExpression() throws SyntaxError.Exception {
    assertExprBothRoundTrip("f()");
    assertExprBothRoundTrip("f(a)");
    assertExprBothRoundTrip("f(a, b = B, c = C, *d, **e)");
    assertExprBothRoundTrip("o.f()");
  }

  @Test
  public void identifier() throws SyntaxError.Exception {
    assertExprBothRoundTrip("foo");
  }

  @Test
  public void indexExpression() throws SyntaxError.Exception {
    assertExprBothRoundTrip("a[i]");
  }

  @Test
  public void integerLiteral() throws SyntaxError.Exception {
    assertExprBothRoundTrip("5");
  }

  @Test
  public void listLiteralShort() throws SyntaxError.Exception {
    assertExprBothRoundTrip("[]");
    assertExprBothRoundTrip("[5]");
    assertExprBothRoundTrip("[5, 6]");
    assertExprBothRoundTrip("()");
    assertExprBothRoundTrip("(5,)");
    assertExprBothRoundTrip("(5, 6)");
  }

  @Test
  public void listLiteralLong() throws SyntaxError.Exception {
    // List literals with enough elements to trigger the abbreviated toString() format.
    assertExprPrettyMatches("[1, 2, 3, 4, 5, 6]", "[1, 2, 3, 4, 5, 6]");
    assertExprTostringMatches("[1, 2, 3, 4, 5, 6]", "[1, 2, 3, 4, <2 more arguments>]");

    assertExprPrettyMatches("(1, 2, 3, 4, 5, 6)", "(1, 2, 3, 4, 5, 6)");
    assertExprTostringMatches("(1, 2, 3, 4, 5, 6)", "(1, 2, 3, 4, <2 more arguments>)");
  }

  @Test
  public void listLiteralNested() throws SyntaxError.Exception {
    // Make sure that the inner list doesn't get abbreviated when the outer list is printed using
    // prettyPrint().
    assertExprPrettyMatches(
        "[1, 2, 3, [10, 20, 30, 40, 50, 60], 4, 5, 6]",
        "[1, 2, 3, [10, 20, 30, 40, 50, 60], 4, 5, 6]");
    // It doesn't matter as much what toString does.
    assertExprTostringMatches(
        "[1, 2, 3, [10, 20, 30, 40, 50, 60], 4, 5, 6]", "[1, 2, 3, <4 more arguments>]");
  }

  @Test
  public void sliceExpression() throws SyntaxError.Exception {
    assertExprBothRoundTrip("a[b:c:d]");
    assertExprBothRoundTrip("a[b:c]");
    assertExprBothRoundTrip("a[b:]");
    assertExprBothRoundTrip("a[:c:d]");
    assertExprBothRoundTrip("a[:c]");
    assertExprBothRoundTrip("a[::d]");
    assertExprBothRoundTrip("a[:]");
  }

  @Test
  public void stringLiteral() throws SyntaxError.Exception {
    assertExprBothRoundTrip("\"foo\"");
    assertExprBothRoundTrip("\"quo\\\"ted\"");
  }

  @Test
  public void unaryOperatorExpression() throws SyntaxError.Exception {
    assertExprPrettyMatches("not True", "not (True)");
    assertExprTostringMatches("not True", "not True");
    assertExprPrettyMatches("-5", "-(5)");
    assertExprTostringMatches("-5", "-5");
  }

  // Statements.

  @Test
  public void assignmentStatement() throws SyntaxError.Exception {
    assertStmtIndentedPrettyMatches("x = y", "  x = y\n");
    assertStmtTostringMatches("x = y", "x = y\n");
  }

  @Test
  public void augmentedAssignmentStatement() throws SyntaxError.Exception {
    assertStmtIndentedPrettyMatches("x += y", "  x += y\n");
    assertStmtTostringMatches("x += y", "x += y\n");
  }

  @Test
  public void expressionStatement() throws SyntaxError.Exception {
    assertStmtIndentedPrettyMatches("5", "  5\n");
    assertStmtTostringMatches("5", "5\n");
  }

  @Test
  public void defStatement() throws SyntaxError.Exception {
    assertStmtIndentedPrettyMatches(
        join("def f(x):",
             "  print(x)"),
        join("  def f(x):",
             "    print(x)",
             ""));
    assertStmtTostringMatches(
        join("def f(x):",
             "  print(x)"),
        "def f(x): ...\n");

    assertStmtIndentedPrettyMatches(
        join("def f(a, b=B, *c, d=D, **e):",
             "  print(x)"),
        join("  def f(a, b=B, *c, d=D, **e):",
             "    print(x)",
             ""));
    assertStmtTostringMatches(
        join(
            "def f(a, b=B, *c, d=D, **e):", //
            "  print(x)"),
        "def f(a, b=B, *c, d=D, **e): ...\n");

    assertStmtIndentedPrettyMatches(
        join("def f():",
             "  pass"),
        join("  def f():",
             "    pass",
             ""));
    assertStmtTostringMatches(
        join("def f():",
             "  pass"),
        "def f(): ...\n");
  }

  @Test
  public void flowStatement() throws SyntaxError.Exception {
    // The parser would complain if we tried to construct them from source.
    Node breakNode = new FlowStatement(TokenKind.BREAK);
    assertIndentedPrettyMatches(breakNode, "  break\n");
    assertTostringMatches(breakNode, "break\n");

    Node continueNode = new FlowStatement(TokenKind.CONTINUE);
    assertIndentedPrettyMatches(continueNode, "  continue\n");
    assertTostringMatches(continueNode, "continue\n");
  }

  @Test
  public void forStatement() throws SyntaxError.Exception {
    assertStmtIndentedPrettyMatches(
        join("for x in y:",
             "  print(x)"),
        join("  for x in y:",
             "    print(x)",
             ""));
    assertStmtTostringMatches(
        join("for x in y:",
             "  print(x)"),
        "for x in y: ...\n");

    assertStmtIndentedPrettyMatches(
        join("for x in y:",
             "  pass"),
        join("  for x in y:",
             "    pass",
             ""));
    assertStmtTostringMatches(
        join("for x in y:",
             "  pass"),
        "for x in y: ...\n");
  }

  @Test
  public void ifStatement() throws SyntaxError.Exception {
    assertStmtIndentedPrettyMatches(
        join("if True:",
             "  print(x)"),
        join("  if True:",
             "    print(x)",
             ""));
    assertStmtTostringMatches(
        join("if True:",
             "  print(x)"),
        "if True: ...\n");

    assertStmtIndentedPrettyMatches(
        join("if True:",
             "  print(x)",
             "elif False:",
             "  print(y)",
             "else:",
             "  print(z)"),
        join("  if True:",
             "    print(x)",
             "  elif False:",
             "    print(y)",
             "  else:",
             "    print(z)",
             ""));
    assertStmtTostringMatches(
        join("if True:",
            "  print(x)",
            "elif False:",
            "  print(y)",
            "else:",
            "  print(z)"),
        "if True: ...\n");
  }

  @Test
  public void loadStatement() throws SyntaxError.Exception {
    // load("foo.bzl", a="A", "B")
    Node loadStatement =
        new LoadStatement(
            new StringLiteral("foo.bzl"),
            ImmutableList.of(
                new LoadStatement.Binding(Identifier.of("a"), Identifier.of("A")),
                new LoadStatement.Binding(Identifier.of("B"), Identifier.of("B"))));
    assertIndentedPrettyMatches(
        loadStatement,
        "  load(\"foo.bzl\", a=\"A\", \"B\")\n");
    assertTostringMatches(
        loadStatement,
        "load(\"foo.bzl\", a=\"A\", \"B\")\n");
  }

  @Test
  public void returnStatement() throws SyntaxError.Exception {
    assertIndentedPrettyMatches(
        new ReturnStatement(new StringLiteral("foo")),
        "  return \"foo\"\n");
    assertTostringMatches(
        new ReturnStatement(new StringLiteral("foo")),
        "return \"foo\"\n");

    assertIndentedPrettyMatches(new ReturnStatement(Identifier.of("None")), "  return None\n");
    assertTostringMatches(new ReturnStatement(Identifier.of("None")), "return None\n");

    assertIndentedPrettyMatches(new ReturnStatement(null), "  return\n");
    assertTostringMatches(new ReturnStatement(null), "return\n");
  }

  // Miscellaneous.

  @Test
  public void buildFileAST() throws SyntaxError.Exception {
    Node node = parseFile("print(x)\nprint(y)");
    assertIndentedPrettyMatches(
        node,
        join("  print(x)",
             "  print(y)",
             ""));
    assertTostringMatches(node, "<StarlarkFile with 2 statements>");
  }

  @Test
  public void comment() throws SyntaxError.Exception {
    Comment node = new Comment("foo");
    assertIndentedPrettyMatches(node, "  # foo");
    assertTostringMatches(node, "foo");
  }

  /* Not tested explicitly because they're covered implicitly by tests for other nodes:
   * - DictExpression.Entry
   * - Argument / Parameter
   * - IfStatements
   */
}
