// 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.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;

/**
 * A base class for Skylark functions, whether builtin or user-defined.
 *
 * <p>Nomenclature: We call "Parameters" the formal parameters of a function definition. We call
 * "Arguments" the actual values supplied at the call site.
 *
 * <p>The outer calling convention is like that of python3, with named parameters that can be
 * mandatory or optional, and also be positional or named-only, and rest parameters for extra
 * positional and keyword arguments. Callers supply a {@code List<Object>} args for positional
 * arguments and a {@code Map<String, Object>} for keyword arguments, where positional arguments
 * will be resolved first, then keyword arguments, with errors for a clash between the two, for
 * missing mandatory parameter, or for unexpected extra positional or keyword argument in absence of
 * rest parameter.
 *
 * <p>The inner calling convention is to pass the underlying method an {@code Object[]} of the
 * type-checked argument values, one per expected parameter, parameters being sorted as documented
 * in {@link FunctionSignature}.
 *
 * <p>The function may provide default values for optional parameters not provided by the caller.
 * These default values can be null if there are no optional parameters or for builtin functions,
 * but not for user-defined functions that have optional parameters.
 */
// TODO(bazel-team):
// Provide optimized argument frobbing depending of FunctionSignature and CallerSignature
// (that FuncallExpression must supply), optimizing for the all-positional and all-keyword cases.
// Also, use better pure maps to minimize map O(n) re-creation events when processing keyword maps.
public abstract class BaseFunction implements StarlarkFunction {

  /**
   * The name of the function.
   *
   * <p>For safe extensibility, this class only retrieves name via the accessor {@link #getName}.
   * This field must be null iff {@link #getName} is overridden.
   */
  @Nullable private final String name;

  // A function signature, including defaults and types
  // never null after it is configured
  @Nullable protected FunctionSignature.WithValues<Object, SkylarkType> signature;

  // Location of the function definition, or null for builtin functions
  // TODO(bazel-team): Or make non-nullable, and use Location.BUILTIN for builtin functions?
  @Nullable protected Location location;

  // Some functions are also Namespaces or other Skylark entities.
  @Nullable protected Class<?> objectType;

  // Documentation for variables, if any
  @Nullable protected List<String> paramDoc;

  // The types actually enforced by the Skylark runtime, as opposed to those enforced by the JVM,
  // or those displayed to the user in the documentation.
  @Nullable protected List<SkylarkType> enforcedArgumentTypes;

  // Defaults to be used when configure(annotation) is called (after the function is constructed).
  @Nullable private Iterable<Object> unconfiguredDefaultValues;
  // The configure(annotation) function will include these defaults in the function signature.
  // We need to supply these defaultValues to the constructor, that will store them here, because
  // they can't be supplied via Java annotations, due to the limitations in the annotation facility.
  // (For extra brownies, we could supply them as Skylark expression strings, to be evaluated by our
  // evaluator without the help of any unconfigured functions, or to be processed at compile-time;
  // but we resolve annotations at runtime for now.)
  // Limitations in Java annotations mean we can't express them in the SkylarkSignature annotation.
  // (In the future, we could parse and evaluate simple Skylark expression strings, but then
  // we'd have to be very careful of circularities during initialization).
  // Note that though we want this list to be immutable, we don't use ImmutableList,
  // because that can't store nulls and nulls are essential for some BuiltinFunction-s.
  // We trust the user not to modify the list behind our back.


  /**
   * Returns the name of this function.
   *
   * <p>A subclass must override this function if a null name is given to this class's constructor.
   */
  public String getName() {
    Preconditions.checkNotNull(name);
    return name;
  }

  /** Returns the signature of this function. */
  @Nullable public FunctionSignature.WithValues<Object, SkylarkType> getSignature() {
    return signature;
  }

  /** This function may also be viewed by Skylark as being of a special ObjectType */
  @Nullable public Class<?> getObjectType() {
    return objectType;
  }

  /** Returns true if the BaseFunction is configured. */
  public boolean isConfigured() {
    return signature != null;
  }

  /**
   * Creates an unconfigured BaseFunction with the given name.
   *
   * <p>The name must be null if called from a subclass constructor where the subclass overrides
   * {@link #getName}; otherwise it must be non-null.
   */
  public BaseFunction(@Nullable String name) {
    this.name = name;
  }

  /**
   * Constructs a BaseFunction with a given name, signature and location.
   *
   * @param name the function name; null iff this is a subclass overriding {@link #getName}
   * @param signature the signature with default values and types
   * @param location the location of function definition
   */
  public BaseFunction(
      @Nullable String name,
      @Nullable FunctionSignature.WithValues<Object, SkylarkType> signature,
      @Nullable Location location) {
    this(name);
    this.signature = signature;
    this.location = location;
  }

  /**
   * Constructs a BaseFunction with a given name, signature.
   *
   * @param name the function name; null iff this is a subclass overriding {@link #getName}
   * @param signature the signature, with default values and types
   */
  public BaseFunction(
      @Nullable String name,
      @Nullable FunctionSignature.WithValues<Object, SkylarkType> signature) {
    this(name, signature, null);
  }

  /**
   * Constructs a BaseFunction with a given name and signature without default values or types.
   *
   * @param name the function name; null iff this is a subclass overriding {@link #getName}
   * @param signature the signature, without default values or types
   */
  public BaseFunction(@Nullable String name, FunctionSignature signature) {
    this(name, FunctionSignature.WithValues.create(signature), null);
  }

  /**
   * Constructs a BaseFunction with a given name and list of unconfigured defaults.
   *
   * @param name the function name; null iff this is a subclass overriding {@link #getName}
   * @param defaultValues a list of default values for the optional arguments to be configured.
   */
  public BaseFunction(@Nullable String name, @Nullable Iterable<Object> defaultValues) {
    this(name);
    this.unconfiguredDefaultValues = defaultValues;
  }

  /** Get parameter documentation as a list corresponding to each parameter */
  public List<String> getParamDoc() {
    return paramDoc;
  }

  /**
   * The size of the array required by the callee.
   */
  protected int getArgArraySize() {
    return signature.getSignature().getShape().getArguments();
  }

  /**
   * The types that will be actually enforced by Skylark itself, so we may skip those already
   * enforced by the JVM during calls to BuiltinFunction, but also so we may lie to the user
   * in the automatically-generated documentation
   */
  public List<SkylarkType> getEnforcedArgumentTypes() {
    return enforcedArgumentTypes;
  }

  /**
   * Process the caller-provided arguments into an array suitable for the callee (this function).
   */
  public Object[] processArguments(List<Object> args,
      @Nullable Map<String, Object> kwargs,
      @Nullable Location loc, @Nullable Environment env)
      throws EvalException {

    Object[] arguments = new Object[getArgArraySize()];

    // extract function signature
    FunctionSignature sig = signature.getSignature();
    FunctionSignature.Shape shape = sig.getShape();
    ImmutableList<String> names = sig.getNames();
    List<Object> defaultValues = signature.getDefaultValues();

    // Note that this variable will be adjusted down if there are extra positionals,
    // after these extra positionals are dumped into starParam.
    int numPositionalArgs = args.size();

    int numMandatoryPositionalParams = shape.getMandatoryPositionals();
    int numOptionalPositionalParams = shape.getOptionalPositionals();
    int numMandatoryNamedOnlyParams = shape.getMandatoryNamedOnly();
    int numOptionalNamedOnlyParams = shape.getOptionalNamedOnly();
    boolean hasStarParam = shape.hasStarArg();
    boolean hasKwParam = shape.hasKwArg();
    int numPositionalParams = numMandatoryPositionalParams + numOptionalPositionalParams;
    int numNamedOnlyParams = numMandatoryNamedOnlyParams + numOptionalNamedOnlyParams;
    int numNamedParams = numPositionalParams + numNamedOnlyParams;
    int kwParamIndex = names.size() - 1; // only valid if hasKwParam

    // (1) handle positional arguments
    if (hasStarParam) {
      // Nota Bene: we collect extra positional arguments in a (tuple,) rather than a [list],
      // and this is actually the same as in Python.
      int starParamIndex = numNamedParams;
      if (numPositionalArgs > numPositionalParams) {
        arguments[starParamIndex] =
            Tuple.copyOf(args.subList(numPositionalParams, numPositionalArgs));
        numPositionalArgs = numPositionalParams; // clip numPositionalArgs
      } else {
        arguments[starParamIndex] = Tuple.empty();
      }
    } else if (numPositionalArgs > numPositionalParams) {
      throw new EvalException(loc,
          numPositionalParams > 0
          ? "too many (" + numPositionalArgs + ") positional arguments in call to " + this
          : this + " does not accept positional arguments, but got " + numPositionalArgs);
    }

    for (int i = 0; i < numPositionalArgs; i++) {
      arguments[i] = args.get(i);
    }

    // (2) handle keyword arguments
    if (kwargs == null || kwargs.isEmpty()) {
      // Easy case (2a): there are no keyword arguments.
      // All arguments were positional, so check we had enough to fill all mandatory positionals.
      if (numPositionalArgs < numMandatoryPositionalParams) {
        throw new EvalException(loc, String.format(
            "insufficient arguments received by %s (got %s, expected at least %s)",
            this, numPositionalArgs, numMandatoryPositionalParams));
      }
      // We had no named argument, so fail if there were mandatory named-only parameters
      if (numMandatoryNamedOnlyParams > 0) {
        throw new EvalException(loc, String.format(
            "missing mandatory keyword arguments in call to %s", this));
      }
      // Fill in defaults for missing optional parameters, that were conveniently grouped together,
      // thanks to the absence of mandatory named-only parameters as checked above.
      if (defaultValues != null) {
        int j = numPositionalArgs - numMandatoryPositionalParams;
        int endOptionalParams = numPositionalParams + numOptionalNamedOnlyParams;
        for (int i = numPositionalArgs; i < endOptionalParams; i++) {
          arguments[i] = defaultValues.get(j++);
        }
      }
      // If there's a kwParam, it's empty.
      if (hasKwParam) {
        // TODO(bazel-team): create a fresh mutable dict, like Python does
        arguments[kwParamIndex] = SkylarkDict.of(env);
      }
    } else if (hasKwParam && numNamedParams == 0) {
      // Easy case (2b): there are no named parameters, but there is a **kwParam.
      // Therefore all keyword arguments go directly to the kwParam.
      // Note that *starParam and **kwParam themselves don't count as named.
      // Also note that no named parameters means no mandatory parameters that weren't passed,
      // and no missing optional parameters for which to use a default. Thus, no loops.
      // NB: not 2a means kwarg isn't null
      arguments[kwParamIndex] = SkylarkDict.copyOf(env, kwargs);
    } else {
      // Hard general case (2c): some keyword arguments may correspond to named parameters
      SkylarkDict<String, Object> kwArg = hasKwParam ? SkylarkDict.of(env) : SkylarkDict.empty();

      // For nicer stabler error messages, start by checking against
      // an argument being provided both as positional argument and as keyword argument.
      ArrayList<String> bothPosKey = new ArrayList<>();
      for (int i = 0; i < numPositionalArgs; i++) {
        String name = names.get(i);
        if (kwargs.containsKey(name)) {
          bothPosKey.add(name);
        }
      }
      if (!bothPosKey.isEmpty()) {
        throw new EvalException(loc,
            String.format("argument%s '%s' passed both by position and by name in call to %s",
                (bothPosKey.size() > 1 ? "s" : ""), Joiner.on("', '").join(bothPosKey), this));
      }

      // Accept the arguments that were passed.
      for (Map.Entry<String, Object> entry : kwargs.entrySet()) {
        String keyword = entry.getKey();
        Object value = entry.getValue();
        int pos = names.indexOf(keyword); // the list should be short, so linear scan is OK.
        if (0 <= pos && pos < numNamedParams) {
          arguments[pos] = value;
        } else {
          if (!hasKwParam) {
            List<String> unexpected = Ordering.natural().sortedCopy(Sets.difference(
                kwargs.keySet(), ImmutableSet.copyOf(names.subList(0, numNamedParams))));
            throw new EvalException(loc, String.format("unexpected keyword%s '%s' in call to %s",
                    unexpected.size() > 1 ? "s" : "", Joiner.on("', '").join(unexpected), this));
          }
          if (kwArg.containsKey(keyword)) {
            throw new EvalException(loc, String.format(
                "%s got multiple values for keyword argument '%s'", this, keyword));
          }
          kwArg.put(keyword, value, loc, env);
        }
      }
      if (hasKwParam) {
        // TODO(bazel-team): create a fresh mutable dict, like Python does
        arguments[kwParamIndex] = SkylarkDict.copyOf(env, kwArg);
      }

      // Check that all mandatory parameters were filled in general case 2c.
      // Note: it's possible that numPositionalArgs > numMandatoryPositionalParams but that's OK.
      for (int i = numPositionalArgs; i < numMandatoryPositionalParams; i++) {
        if (arguments[i] == null) {
          throw new EvalException(loc, String.format(
              "missing mandatory positional argument '%s' while calling %s",
              names.get(i), this));
        }
      }

      int endMandatoryNamedOnlyParams = numPositionalParams + numMandatoryNamedOnlyParams;
      for (int i = numPositionalParams; i < endMandatoryNamedOnlyParams; i++) {
        if (arguments[i] == null) {
          throw new EvalException(loc, String.format(
              "missing mandatory named-only argument '%s' while calling %s",
              names.get(i), this));
        }
      }

      // Get defaults for those parameters that weren't passed.
      if (defaultValues != null) {
        for (int i = Math.max(numPositionalArgs, numMandatoryPositionalParams);
             i < numPositionalParams; i++) {
          if (arguments[i] == null) {
            arguments[i] = defaultValues.get(i - numMandatoryPositionalParams);
          }
        }
        int numMandatoryParams = numMandatoryPositionalParams + numMandatoryNamedOnlyParams;
        for (int i = numMandatoryParams + numOptionalPositionalParams; i < numNamedParams; i++) {
          if (arguments[i] == null) {
            arguments[i] = defaultValues.get(i - numMandatoryParams);
          }
        }
      }
    } // End of general case 2c for argument passing.

    return arguments;
  }

  /** check types and convert as required */
  protected void canonicalizeArguments(Object[] arguments, Location loc) throws EvalException {
    // TODO(bazel-team): maybe link syntax.SkylarkType and package.Type,
    // so we can simultaneously typecheck and convert?
    // Note that a BuiltinFunction already does typechecking of simple types.

    List<SkylarkType> types = getEnforcedArgumentTypes();

    // Check types, if supplied
    if (types == null) {
      return;
    }
    int length = types.size();
    for (int i = 0; i < length; i++) {
      Object value = arguments[i];
      SkylarkType type = types.get(i);
      if (value != null && type != null && !type.contains(value)) {
        List<String> names = signature.getSignature().getNames();
        throw new EvalException(loc,
            String.format("expected %s for '%s' while calling %s but got %s instead: %s",
                type, names.get(i), getName(), EvalUtils.getDataTypeName(value, true), value));
      }
    }
  }

  /**
   * Returns the environment for the scope of this function.
   *
   * <p>Since this is a BaseFunction, we don't create a new environment.
   */
  @SuppressWarnings("unused") // For the exception
  protected Environment getOrCreateChildEnvironment(Environment parent) throws EvalException {
    return parent;
  }

  /**
   * The outer calling convention to a BaseFunction.
   *
   * @param args a list of all positional arguments (as in *starArg)
   * @param kwargs a map for key arguments (as in **kwArgs)
   * @param ast the expression for this function's definition
   * @param env the Environment in the function is called
   * @return the value resulting from evaluating the function with the given arguments
   * @throws EvalException-s containing source information.
   */
  public Object call(List<Object> args,
      @Nullable Map<String, Object> kwargs,
      @Nullable FuncallExpression ast,
      Environment env)
      throws EvalException, InterruptedException {
    Preconditions.checkState(isConfigured(), "Function %s was not configured", getName());

    // ast is null when called from Java (as there's no Skylark call site).
    Location loc = ast == null ? Location.BUILTIN : ast.getLocation();

    Object[] arguments = processArguments(args, kwargs, loc, env);
    return callWithArgArray(arguments, ast, env, location);
  }

  /**
   * Inner call to a BaseFunction subclasses need to @Override this method.
   *
   * @param args an array of argument values sorted as per the signature.
   * @param ast the source code for the function if user-defined
   * @param env the lexical environment of the function call
   * @throws InterruptedException may be thrown in the function implementations.
   */
  // Don't make it abstract, so that subclasses may be defined that @Override the outer call() only.
  protected Object call(Object[] args, @Nullable FuncallExpression ast, Environment env)
      throws EvalException, InterruptedException {
    throw new EvalException(
        (ast == null) ? Location.BUILTIN : ast.getLocation(),
        String.format("function %s not implemented", getName()));
  }

  /**
   * The outer calling convention to a BaseFunction. This function expects all arguments to have
   * been resolved into positional ones.
   *
   * @param ast the expression for this function's definition
   * @param env the Environment in the function is called
   * @return the value resulting from evaluating the function with the given arguments
   * @throws EvalException-s containing source information.
   */
  public Object callWithArgArray(
      Object[] arguments, @Nullable FuncallExpression ast, Environment env, Location loc)
      throws EvalException, InterruptedException {
    Preconditions.checkState(isConfigured(), "Function %s was not configured", getName());
    canonicalizeArguments(arguments, loc);

    try {
      if (Callstack.enabled) {
        Callstack.push(this);
      }
      return call(arguments, ast, env);
    } finally {
      if (Callstack.enabled) {
        Callstack.pop();
      }
    }
  }

  /**
   * Render this object in the form of an equivalent Python function signature.
   */
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append(getName());
    if (signature != null) {
      sb.append('(');
      signature.toStringBuilder(sb);
      sb.append(')');
    } // if unconfigured, don't even output parentheses
    return sb.toString();
  }

  /** Configure a BaseFunction from a @SkylarkSignature annotation */
  public void configure(SkylarkSignature annotation) {
    Preconditions.checkState(!isConfigured()); // must not be configured yet

    this.paramDoc = new ArrayList<>();
    this.signature = SkylarkSignatureProcessor.getSignatureForCallable(
        getName(), annotation, unconfiguredDefaultValues, paramDoc, getEnforcedArgumentTypes());
    this.objectType = annotation.objectType().equals(Object.class)
        ? null : annotation.objectType();
    configure();
  }

  /** Configure a function based on its signature */
  protected void configure() {
    // this function is called after the signature was initialized
    Preconditions.checkState(signature != null);
    enforcedArgumentTypes = signature.getTypes();
  }

  protected boolean hasSelfArgument() {
    Class<?> clazz = getObjectType();
    if (clazz == null) {
      return false;
    }
    List<SkylarkType> types = signature.getTypes();
    ImmutableList<String> names = signature.getSignature().getNames();

    return (!types.isEmpty() && types.get(0).canBeCastTo(clazz))
        || (!names.isEmpty() && names.get(0).equals("self"));
  }

  protected String getObjectTypeString() {
    Class<?> clazz = getObjectType();
    if (clazz == null) {
      return "";
    }
    return EvalUtils.getDataTypeNameFromClass(clazz, false) + ".";
  }

  /**
   * Returns [class.]function (depending on whether func belongs to a class).
   */
  public String getFullName() {
    return String.format("%s%s", getObjectTypeString(), getName());
  }

  /**
   * Returns the signature as "[className.]methodName(name1: paramType1, name2: paramType2, ...)"
   */
  public String getShortSignature() {
    StringBuilder builder = new StringBuilder();
    boolean hasSelf = hasSelfArgument();

    builder.append(getFullName()).append("(");
    signature.toStringBuilder(builder, false, false, hasSelf);
    builder.append(")");

    return builder.toString();
  }

  /**
   * Prints the types of the first {@code howManyArgsToPrint} given arguments as
   * "(type1, type2, ...)"
   */
  protected String printTypeString(Object[] args, int howManyArgsToPrint) {
    StringBuilder builder = new StringBuilder();
    builder.append("(");

    int start = hasSelfArgument() ? 1 : 0;
    for (int pos = start; pos < howManyArgsToPrint; ++pos) {
      builder.append(EvalUtils.getDataTypeName(args[pos]));

      if (pos < howManyArgsToPrint - 1) {
        builder.append(", ");
      }
    }
    builder.append(")");
    return builder.toString();
  }

  @Override
  public boolean equals(@Nullable Object other) {
    if (other instanceof BaseFunction) {
      BaseFunction that = (BaseFunction) other;
      // In theory, the location alone unambiguously identifies a given function. However, in
      // some test cases the location might not have a valid value, thus we also check the name.
      return Objects.equals(this.getName(), that.getName())
          && Objects.equals(this.location, that.location);
    }
    return false;
  }

  @Override
  public int hashCode() {
    return Objects.hash(getName(), location);
  }

  @Nullable
  public Location getLocation() {
    return location;
  }

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

  @Override
  public void repr(SkylarkPrinter printer) {
    printer.append("<function " + getName() + ">");
  }
}
