// Copyright 2019 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 java.util.List;

/** A pretty-printer for Starlark syntax trees. */
final class NodePrinter {

  private final StringBuilder buf;
  private int indent;

  NodePrinter(StringBuilder buf) {
    this.buf = buf;
  }

  // Constructor exposed to legacy tests.
  // TODO(adonovan): rewrite the tests not to care about the indent parameter.
  NodePrinter(StringBuilder buf, int indent) {
    this.buf = buf;
    this.indent = indent;
  }

  // Main entry point for an arbitrary node.
  // Called by Node.prettyPrint.
  void printNode(Node n) {
    if (n instanceof Expression) {
      printExpr((Expression) n);

    } else if (n instanceof Statement) {
      printStmt((Statement) n);

    } else if (n instanceof StarlarkFile) {
      StarlarkFile file = (StarlarkFile) n;
      // Only statements are printed, not comments.
      for (Statement stmt : file.getStatements()) {
        printStmt(stmt);
      }

    } else if (n instanceof Comment) {
      Comment comment = (Comment) n;
      // We can't really print comments in the right place anyway,
      // due to how their relative order is lost in the representation
      // of StarlarkFile. So don't bother word-wrapping and just print
      // it on a single line.
      printIndent();
      buf.append("# ");
      buf.append(comment.getValue());

    } else if (n instanceof Argument) {
      printArgument((Argument) n);

    } else if (n instanceof Parameter) {
      printParameter((Parameter) n);

    } else if (n instanceof DictExpression.Entry) {
      printDictEntry((DictExpression.Entry) n);

    } else {
      throw new IllegalArgumentException("unexpected: " + n.getClass());
    }
  }

  private void printSuite(List<Statement> statements) {
    // A suite is non-empty; pass statements are explicit.
    indent++;
    for (Statement stmt : statements) {
      printStmt(stmt);
    }
    indent--;
  }

  private void printIndent() {
    for (int i = 0; i < indent; i++) {
      buf.append("  ");
    }
  }

  private void printArgument(Argument arg) {
    if (arg instanceof Argument.Positional) {
      // nop
    } else if (arg instanceof Argument.Keyword) {
      buf.append(((Argument.Keyword) arg).getIdentifier().getName());
      buf.append(" = ");
    } else if (arg instanceof Argument.Star) {
      buf.append('*');
    } else if (arg instanceof Argument.StarStar) {
      buf.append("**");
    }
    printExpr(arg.getValue());
  }

  private void printParameter(Parameter param) {
    if (param instanceof Parameter.Mandatory) {
      buf.append(param.getName());
    } else if (param instanceof Parameter.Optional) {
      buf.append(param.getName());
      buf.append('=');
      printExpr(param.getDefaultValue());
    } else if (param instanceof Parameter.Star) {
      buf.append('*');
      if (param.getName() != null) {
        buf.append(param.getName());
      }
    } else if (param instanceof Parameter.StarStar) {
      buf.append("**");
      buf.append(param.getName());
    }
  }

  private void printDictEntry(DictExpression.Entry e) {
    printExpr(e.getKey());
    buf.append(": ");
    printExpr(e.getValue());
  }

  // Appends "def f(a, ..., z):" to the buf.
  // Also used by DefStatement.toString.
  void printDefSignature(DefStatement def) {
    buf.append("def ");
    printExpr(def.getIdentifier());
    buf.append('(');
    String sep = "";
    for (Parameter param : def.getParameters()) {
      buf.append(sep);
      printParameter(param);
      sep = ", ";
    }
    buf.append("):");
  }

  private void printStmt(Statement s) {
    printIndent();

    switch (s.kind()) {
      case ASSIGNMENT:
        {
          AssignmentStatement stmt = (AssignmentStatement) s;
          printExpr(stmt.getLHS());
          buf.append(' ');
          if (stmt.isAugmented()) {
            buf.append(stmt.getOperator());
          }
          buf.append("= ");
          printExpr(stmt.getRHS());
          buf.append('\n');
          break;
        }

      case EXPRESSION:
        {
          ExpressionStatement stmt = (ExpressionStatement) s;
          printExpr(stmt.getExpression());
          buf.append('\n');
          break;
        }

      case FLOW:
        {
          FlowStatement stmt = (FlowStatement) s;
          buf.append(stmt.getKind()).append('\n');
          break;
        }

      case FOR:
        {
          ForStatement stmt = (ForStatement) s;
          buf.append("for ");
          printExpr(stmt.getLHS());
          buf.append(" in ");
          printExpr(stmt.getCollection());
          buf.append(":\n");
          printSuite(stmt.getBlock());
          break;
        }

      case DEF:
        {
          DefStatement stmt = (DefStatement) s;
          printDefSignature(stmt);
          buf.append('\n');
          printSuite(stmt.getStatements());
          break;
        }

      case IF:
        {
          IfStatement stmt = (IfStatement) s;
          buf.append(stmt.isElif() ? "elif " : "if ");
          printExpr(stmt.getCondition());
          buf.append(":\n");
          printSuite(stmt.getThenBlock());
          List<Statement> elseBlock = stmt.getElseBlock();
          if (elseBlock != null) {
            if (elseBlock.size() == 1
                && elseBlock.get(0) instanceof IfStatement
                && ((IfStatement) elseBlock.get(0)).isElif()) {
              printStmt(elseBlock.get(0));
            } else {
              printIndent();
              buf.append("else:\n");
              printSuite(elseBlock);
            }
          }
          break;
        }

      case LOAD:
        {
          LoadStatement stmt = (LoadStatement) s;
          buf.append("load(");
          printExpr(stmt.getImport());
          for (LoadStatement.Binding binding : stmt.getBindings()) {
            buf.append(", ");
            Identifier local = binding.getLocalName();
            String origName = binding.getOriginalName().getName();
            if (origName.equals(local.getName())) {
              buf.append('"');
              printExpr(local);
              buf.append('"');
            } else {
              printExpr(local);
              buf.append("=\"");
              buf.append(origName);
              buf.append('"');
            }
          }
          buf.append(")\n");
          break;
        }

      case RETURN:
        {
          ReturnStatement stmt = (ReturnStatement) s;
          buf.append("return");
          if (stmt.getReturnExpression() != null) {
            buf.append(' ');
            printExpr(stmt.getReturnExpression());
          }
          buf.append('\n');
          break;
        }
    }
  }

  private void printExpr(Expression expr) {
    switch (expr.kind()) {
      case BINARY_OPERATOR:
        {
          BinaryOperatorExpression binop = (BinaryOperatorExpression) expr;
          // TODO(bazel-team): retain parentheses in the syntax tree so we needn't
          // conservatively emit them here.
          buf.append('(');
          printExpr(binop.getX());
          buf.append(' ');
          buf.append(binop.getOperator());
          buf.append(' ');
          printExpr(binop.getY());
          buf.append(')');
          break;
        }

      case COMPREHENSION:
        {
          Comprehension comp = (Comprehension) expr;
          buf.append(comp.isDict() ? '{' : '[');
          printNode(comp.getBody()); // Expression or DictExpression.Entry
          for (Comprehension.Clause clause : comp.getClauses()) {
            buf.append(' ');
            if (clause instanceof Comprehension.For) {
              Comprehension.For forClause = (Comprehension.For) clause;
              buf.append("for ");
              printExpr(forClause.getVars());
              buf.append(" in ");
              printExpr(forClause.getIterable());
            } else {
              Comprehension.If ifClause = (Comprehension.If) clause;
              buf.append("if ");
              printExpr(ifClause.getCondition());
            }
          }
          buf.append(comp.isDict() ? '}' : ']');
          break;
        }

      case CONDITIONAL:
        {
          ConditionalExpression cond = (ConditionalExpression) expr;
          printExpr(cond.getThenCase());
          buf.append(" if ");
          printExpr(cond.getCondition());
          buf.append(" else ");
          printExpr(cond.getElseCase());
          break;
        }

      case DICT_EXPR:
        {
          DictExpression dictexpr = (DictExpression) expr;
          buf.append("{");
          String sep = "";
          for (DictExpression.Entry entry : dictexpr.getEntries()) {
            buf.append(sep);
            printDictEntry(entry);
            sep = ", ";
          }
          buf.append("}");
          break;
        }

      case DOT:
        {
          DotExpression dot = (DotExpression) expr;
          printExpr(dot.getObject());
          buf.append('.');
          printExpr(dot.getField());
          break;
        }

      case CALL:
        {
          CallExpression call = (CallExpression) expr;
          printExpr(call.getFunction());
          buf.append('(');
          String sep = "";
          for (Argument arg : call.getArguments()) {
            buf.append(sep);
            printArgument(arg);
            sep = ", ";
          }
          buf.append(')');
          break;
        }

      case IDENTIFIER:
        buf.append(((Identifier) expr).getName());
        break;

      case INDEX:
        {
          IndexExpression index = (IndexExpression) expr;
          printExpr(index.getObject());
          buf.append('[');
          printExpr(index.getKey());
          buf.append(']');
          break;
        }

      case INTEGER_LITERAL:
        {
          buf.append(((IntegerLiteral) expr).getValue());
          break;
        }

      case LIST_EXPR:
        {
          ListExpression list = (ListExpression) expr;
          buf.append(list.isTuple() ? '(' : '[');
          String sep = "";
          for (Expression e : list.getElements()) {
            buf.append(sep);
            printExpr(e);
            sep = ", ";
          }
          if (list.isTuple() && list.getElements().size() == 1) {
            buf.append(',');
          }
          buf.append(list.isTuple() ? ')' : ']');
          break;
        }

      case SLICE:
        {
          SliceExpression slice = (SliceExpression) expr;
          printExpr(slice.getObject());
          buf.append('[');
          // The first separator colon is unconditional.
          // The second separator appears only if step is printed.
          if (slice.getStart() != null) {
            printExpr(slice.getStart());
          }
          buf.append(':');
          if (slice.getStop() != null) {
            printExpr(slice.getStop());
          }
          if (slice.getStep() != null) {
            buf.append(':');
            printExpr(slice.getStep());
          }
          buf.append(']');
          break;
        }

      case STRING_LITERAL:
        {
          StringLiteral literal = (StringLiteral) expr;
          String value = literal.getValue();

          // TODO(adonovan): record the raw text of string (and integer) literals
          // so that we can use the syntax tree for source modification tools.
          // However, that may come with a memory cost until we start compiling
          // (at which point the cost is only transient).
          // For now, just simulate the behavior of repr(str).
          buf.append('"');
          for (int i = 0; i < value.length(); i++) {
            char c = value.charAt(i);
            switch (c) {
              case '"':
                buf.append("\\\"");
                break;
              case '\\':
                buf.append("\\\\");
                break;
              case '\r':
                buf.append("\\r");
                break;
              case '\n':
                buf.append("\\n");
                break;
              case '\t':
                buf.append("\\t");
                break;
              default:
                // The Starlark spec (and lexer) are far from complete here,
                // and it's hard to come up with a clean semantics for
                // string escapes that serves Java (UTF-16) and Go (UTF-8).
                // Clearly string literals should not contain non-printable
                // characters. For now we'll continue to pretend that all
                // non-printables are < 32, but this obviously false.
                if (c < 32) {
                  buf.append(String.format("\\x%02x", (int) c));
                } else {
                  buf.append(c);
                }
            }
          }
          buf.append('"');
          break;
        }

      case UNARY_OPERATOR:
        {
          UnaryOperatorExpression unop = (UnaryOperatorExpression) expr;
          // TODO(bazel-team): retain parentheses in the syntax tree so we needn't
          // conservatively emit them here.
          buf.append(unop.getOperator() == TokenKind.NOT ? "not " : unop.getOperator().toString());
          buf.append('(');
          printExpr(unop.getX());
          buf.append(')');
          break;
        }
    }
  }
}
