// 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.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
import java.util.List;
import javax.annotation.Nullable;

/**
 * Syntax node for a function argument.
 *
 * <p>Argument is a base class for arguments passed in a call (@see Argument.Passed)
 * or defined as part of a function definition (@see Parameter).
 * It is notably used by some {@link Parser} and printer functions.
 */
public abstract class Argument extends ASTNode {

  public boolean isStar() {
    return false;
  }

  public boolean isStarStar() {
    return false;
  }

  /**
   * Argument.Passed is the class of arguments passed in a function call
   * (as opposed to being used in a definition -- @see Parameter for that).
   * Argument.Passed is usually what we mean when informally say "argument".
   *
   * <p>An Argument.Passed can be Positional, Keyword, Star, or StarStar.
   */
  public abstract static class Passed extends Argument {
    /** the value to be passed by this argument */
    protected final Expression value;

    private Passed(Expression value) {
      this.value = Preconditions.checkNotNull(value);
    }

    public boolean isPositional() {
      return false;
    }

    public boolean isKeyword() {
      return false;
    }

    @Nullable
    public String getName() { // only for keyword arguments
      return null;
    }

    public Expression getValue() {
      return value;
    }

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

  /** positional argument: Expression */
  @AutoCodec
  public static final class Positional extends Passed {

    public Positional(Expression value) {
      super(value);
    }

    @Override
    public boolean isPositional() {
      return true;
    }

    @Override
    public void prettyPrint(Appendable buffer) throws IOException {
      value.prettyPrint(buffer);
    }
  }

  /** keyword argument: K = Expression */
  @AutoCodec
  public static final class Keyword extends Passed {

    final String name;

    public Keyword(String name, Expression value) {
      super(value);
      this.name = name;
    }

    @Override
    public String getName() {
      return name;
    }

    @Override
    public boolean isKeyword() {
      return true;
    }

    @Override
    public void prettyPrint(Appendable buffer) throws IOException {
      buffer.append(name);
      buffer.append(" = ");
      value.prettyPrint(buffer);
    }
  }

  /** positional rest (starred) argument: *Expression */
  @AutoCodec
  public static final class Star extends Passed {

    public Star(Expression value) {
      super(value);
    }

    @Override
    public boolean isStar() {
      return true;
    }

    @Override
    public void prettyPrint(Appendable buffer) throws IOException {
      buffer.append('*');
      value.prettyPrint(buffer);
    }
  }

  /** keyword rest (star_starred) parameter: **Expression */
  @AutoCodec
  public static final class StarStar extends Passed {

    public StarStar(Expression value) {
      super(value);
    }

    @Override
    public boolean isStarStar() {
      return true;
    }

    @Override
    public void prettyPrint(Appendable buffer) throws IOException {
      buffer.append("**");
      value.prettyPrint(buffer);
    }
  }

  /** Some arguments failed to satisfy python call convention strictures */
  protected static class ArgumentException extends Exception {
    /** construct an ArgumentException from a message only */
    public ArgumentException(String message) {
      super(message);
    }
  }

  /**
   * Validate that the list of Argument's, whether gathered by the Parser or from annotations,
   * satisfies the requirements of the Python calling conventions: all Positional's first,
   * at most one Star, at most one StarStar, at the end only.
   */
  public static void validateFuncallArguments(List<Passed> arguments)
      throws ArgumentException {
    boolean hasNamed = false;
    boolean hasStar = false;
    boolean hasKwArg = false;
    for (Passed arg : arguments) {
      if (hasKwArg) {
        throw new ArgumentException("argument after **kwargs");
      }
      if (arg.isPositional()) {
        if (hasNamed) {
          throw new ArgumentException("non-keyword arg after keyword arg");
        } else if (arg.isStar()) {
          throw new ArgumentException("only named arguments may follow *expression");
        }
      } else if (arg.isKeyword()) {
        hasNamed = true;
      } else if (arg.isStar()) {
        if (hasStar) {
          throw new ArgumentException("more than one *stararg");
        }
        hasStar = true;
      } else {
        hasKwArg = true;
      }
    }
  }

  @Override
  public final void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
    prettyPrint(buffer);
  }

  @Override
  public abstract void prettyPrint(Appendable buffer) throws IOException;
}
