// Copyright 2014 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 com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.util.List;

/** Syntax node for an if/else statement. */
public final class IfStatement extends Statement {

  /**
   * Syntax node for an [el]if statement.
   *
   * <p>This extends Statement, but it is not actually an independent statement in the grammar. We
   * should probably eliminate it in favor of a recursive representation of if/else chains.
   */
  public static final class ConditionalStatements extends Statement {

    private final Expression condition;
    private final ImmutableList<Statement> statements;

    public ConditionalStatements(Expression condition, List<Statement> statements) {
      this.condition = Preconditions.checkNotNull(condition);
      this.statements = ImmutableList.copyOf(statements);
    }

    // No prettyPrint function; handled directly by IfStatement#prettyPrint.
    @Override
    public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
      throw new UnsupportedOperationException("Cannot pretty print ConditionalStatements node");
    }

    @Override
    public String toString() {
      return "[el]if " + condition + ": " + statements + "\n";
    }

    @Override
    public void accept(SyntaxTreeVisitor visitor) {
      visitor.visit(this);
    }

    @Override
    public Kind kind() {
      return Kind.CONDITIONAL;
    }

    public Expression getCondition() {
      return condition;
    }

    public ImmutableList<Statement> getStatements() {
      return statements;
    }
  }

  /** "if" or "elif" clauses. Must be non-empty. */
  private final ImmutableList<ConditionalStatements> thenBlocks;
  private final ImmutableList<Statement> elseBlock;

  /**
   * Constructs a if-elif-else statement. The else part is mandatory, but the list may be empty.
   * ThenBlocks has to have at least one element.
   */
  public IfStatement(List<ConditionalStatements> thenBlocks, List<Statement> elseBlock) {
    Preconditions.checkArgument(!thenBlocks.isEmpty());
    this.thenBlocks = ImmutableList.copyOf(thenBlocks);
    this.elseBlock = ImmutableList.copyOf(elseBlock);
  }

  public ImmutableList<ConditionalStatements> getThenBlocks() {
    return thenBlocks;
  }

  public ImmutableList<Statement> getElseBlock() {
    return elseBlock;
  }

  @Override
  public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
    String clauseWord = "if ";
    for (ConditionalStatements condStmt : thenBlocks) {
      printIndent(buffer, indentLevel);
      buffer.append(clauseWord);
      condStmt.getCondition().prettyPrint(buffer);
      buffer.append(":\n");
      printSuite(buffer, condStmt.getStatements(), indentLevel);
      clauseWord = "elif ";
    }
    if (!elseBlock.isEmpty()) {
      printIndent(buffer, indentLevel);
      buffer.append("else:\n");
      printSuite(buffer, elseBlock, indentLevel);
    }
  }

  @Override
  public String toString() {
    return String.format("if %s: ...\n", thenBlocks.get(0).getCondition());
  }

  @Override
  public void accept(SyntaxTreeVisitor visitor) {
    visitor.visit(this);
  }

  @Override
  public Kind kind() {
    return Kind.IF;
  }
}
