// Copyright 2018 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 com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
import java.util.Arrays;
import javax.annotation.Nullable;

/** A value class for storing {@link Param} metadata to avoid using Java proxies. */
public final class ParamDescriptor {

  private final String name;
  private final String defaultValue;
  private final Class<?> type;
  private final ImmutableList<ParamTypeDescriptor> allowedTypes;
  private final Class<?> generic1;
  private final boolean noneable;
  private final boolean named;
  private final boolean positional;
  // While the type can be inferred completely by the Param annotation, this tuple allows for the
  // type of a given parameter to be determined only once, as it is an expensive operation.
  private final SkylarkType skylarkType;

  // The next two fields relate to toggling this parameter via semantic flag -- they will
  // be null if and only if this parameter is enabled, and will otherwise contain information
  // about what to do with the disabled parameter. (If the parameter is 'disabled', it will be
  // treated as unusable from Starlark.)

  // The value of this disabled parameter (as interpreted in Starlark) will be passed to the Java
  // method.
  @Nullable private final String valueOverride;
  // The flag responsible for disabling this parameter. If a user attempts to use this disabled
  // parameter from Starlark, this identifier can be used to create the appropriate error message.
  @Nullable private final FlagIdentifier flagResponsibleForDisable;

  private ParamDescriptor(
      String name,
      String defaultValue,
      Class<?> type,
      ImmutableList<ParamTypeDescriptor> allowedTypes,
      Class<?> generic1,
      boolean noneable,
      boolean named,
      boolean positional,
      SkylarkType skylarkType,
      @Nullable String valueOverride,
      @Nullable FlagIdentifier flagResponsibleForDisable) {
    this.name = name;
    this.defaultValue = defaultValue;
    this.type = type;
    this.allowedTypes = allowedTypes;
    this.generic1 = generic1;
    this.noneable = noneable;
    this.named = named;
    this.positional = positional;
    this.skylarkType = skylarkType;
    this.valueOverride = valueOverride;
    this.flagResponsibleForDisable = flagResponsibleForDisable;
  }

  static ParamDescriptor of(Param param, StarlarkSemantics starlarkSemantics) {
    ImmutableList<ParamTypeDescriptor> allowedTypes =
        Arrays.stream(param.allowedTypes())
            .map(ParamTypeDescriptor::of)
            .collect(ImmutableList.toImmutableList());
    Class<?> type = param.type();
    Class<?> generic = param.generic1();
    boolean noneable = param.noneable();

    boolean isParamEnabledWithCurrentSemantics =
        starlarkSemantics.isFeatureEnabledBasedOnTogglingFlags(
            param.enableOnlyWithFlag(), param.disableWithFlag());

    String valueOverride = null;
    FlagIdentifier flagResponsibleForDisable = FlagIdentifier.NONE;
    if (!isParamEnabledWithCurrentSemantics) {
      valueOverride = param.valueWhenDisabled();
      flagResponsibleForDisable =
          param.enableOnlyWithFlag() != FlagIdentifier.NONE
              ? param.enableOnlyWithFlag()
              : param.disableWithFlag();
    }
    return new ParamDescriptor(
        param.name(),
        param.defaultValue(),
        type,
        allowedTypes,
        generic,
        noneable,
        isNamed(param, starlarkSemantics),
        param.positional(),
        getType(type, generic, allowedTypes, noneable),
        valueOverride,
        flagResponsibleForDisable);
  }

  private static boolean isNamed(Param param, StarlarkSemantics starlarkSemantics) {
    if (param.named()) {
      return true;
    }
    return param.legacyNamed() && !starlarkSemantics.experimentalRestrictNamedParams();
  }

  /** @see Param#name() */
  public String getName() {
    return name;
  }

  /** @see Param#allowedTypes() */
  public ImmutableList<ParamTypeDescriptor> getAllowedTypes() {
    return allowedTypes;
  }

  /** @see Param#type() */
  public Class<?> getType() {
    return type;
  }

  private static SkylarkType getType(
      Class<?> type,
      Class<?> generic,
      ImmutableList<ParamTypeDescriptor> allowedTypes,
      boolean noneable) {
    SkylarkType result = SkylarkType.BOTTOM;
    if (!allowedTypes.isEmpty()) {
      Preconditions.checkState(Object.class.equals(type));
      for (ParamTypeDescriptor paramType : allowedTypes) {
        SkylarkType t =
            paramType.getGeneric1() != Object.class
                ? SkylarkType.of(paramType.getType(), paramType.getGeneric1())
                : SkylarkType.of(paramType.getType());
        result = SkylarkType.Union.of(result, t);
      }
    } else {
      result = generic != Object.class ? SkylarkType.of(type, generic) : SkylarkType.of(type);
    }

    if (noneable) {
      result = SkylarkType.Union.of(result, SkylarkType.NONE);
    }
    return result;
  }

  /** @see Param#generic1() */
  public Class<?> getGeneric1() {
    return generic1;
  }

  /** @see Param#noneable() */
  public boolean isNoneable() {
    return noneable;
  }

  /** @see Param#positional() */
  public boolean isPositional() {
    return positional;
  }

  /** @see Param#named() */
  public boolean isNamed() {
    return named;
  }

  /** @see Param#defaultValue() */
  public String getDefaultValue() {
    return defaultValue;
  }

  SkylarkType getSkylarkType() {
    return skylarkType;
  }

  /** Returns true if this parameter is disabled under the current skylark semantic flags. */
  public boolean isDisabledInCurrentSemantics() {
    return valueOverride != null;
  }

  /**
   * Returns the value the parameter should take, given that the parameter is disabled under the
   * current skylark semantics.
   *
   * @throws IllegalStateException if invoked when {@link #isDisabledInCurrentSemantics()} is false
   */
  public String getValueOverride() {
    Preconditions.checkState(
        isDisabledInCurrentSemantics(),
        "parameter is not disabled under the current semantic flags. getValueOverride should be "
            + "called only if isParameterDisabled is true");
    return valueOverride;
  }

  /**
   * Returns the flag responsible for disabling this parameter, given that the parameter is disabled
   * under the current skylark semantics.
   *
   * @throws IllegalStateException if invoked when {@link #isDisabledInCurrentSemantics()} is false
   */
  public FlagIdentifier getFlagResponsibleForDisable() {
    Preconditions.checkState(
        isDisabledInCurrentSemantics(),
        "parameter is not disabled under the current semantic flags. getFlagResponsibleForDisable "
            + " should be called only if isParameterDisabled is true");
    return flagResponsibleForDisable;
  }
}
