// Copyright 2023 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.packages;

import com.google.auto.value.AutoValue;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.devtools.build.lib.analysis.config.FeatureSet;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.CollectionUtils;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.List;
import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Starlark;

/**
 * A group of {@link Package} argument values that may be provided by `package()` or `repo()` calls.
 *
 * <p>Unless otherwise specified, these are only used when the rule does not provide an explicit
 * override value in the associated attribute.
 */
@AutoValue
public abstract class PackageArgs {
  public static final PackageArgs EMPTY = PackageArgs.builder().build();

  public static final PackageArgs DEFAULT =
      PackageArgs.builder()
          .setDefaultVisibility(RuleVisibility.PRIVATE)
          .setDefaultTestOnly(false)
          .setFeatures(FeatureSet.EMPTY)
          .setLicense(License.NO_LICENSE)
          .setDefaultCompatibleWith(ImmutableSet.of())
          .setDefaultRestrictedTo(ImmutableSet.of())
          .setDefaultPackageMetadata(ImmutableList.of())
          .build();

  /** The default visibility value for the package. */
  @Nullable
  public abstract RuleVisibility defaultVisibility();

  /** The default testonly value for the package. */
  @Nullable
  public abstract Boolean defaultTestOnly();

  /** The default deprecation value for the package. */
  @Nullable
  public abstract String defaultDeprecation();

  /**
   * The default (generally C/C++) features value for the package.
   *
   * <p>Note that this is actually additive with features set by a rule where the rule has priority
   * for turning specific features on or off.
   */
  public abstract FeatureSet features();

  /** The default license value for the package. */
  @Nullable
  public abstract License license();

  /** The default {@link RuleClass#COMPATIBLE_ENVIRONMENT_ATTR} value for the package. */
  @Nullable
  public abstract ImmutableSet<Label> defaultCompatibleWith();

  /** The default {@link RuleClass#RESTRICTED_ENVIRONMENT_ATTR} value for the package. */
  @Nullable
  public abstract ImmutableSet<Label> defaultRestrictedTo();

  /** The default package metadata list value for the package. */
  @Nullable
  public abstract ImmutableList<Label> defaultPackageMetadata();

  // TODO(blaze-team): this should just act like other attributes in that
  //   it is public and does not have getters defined
  /** The default (C/C++) header strictness checking mode for the package. */
  @Nullable
  abstract String defaultHdrsCheck();

  /** Gets the default header checking mode. */
  public String getDefaultHdrsCheck() {
    return defaultHdrsCheck() != null ? defaultHdrsCheck() : "strict";
  }

  /** Returns whether the default header checking mode has been set or it is the default value. */
  public boolean isDefaultHdrsCheckSet() {
    return defaultHdrsCheck() != null;
  }

  public static Builder builder() {
    return new AutoValue_PackageArgs.Builder().setFeatures(FeatureSet.EMPTY);
  }

  abstract Builder toBuilder();

  /** Builder type for {@link PackageArgs}. */
  @AutoValue.Builder
  public abstract static class Builder {
    public abstract Builder setDefaultVisibility(RuleVisibility x);

    public abstract Builder setDefaultTestOnly(Boolean x);

    public abstract Builder setDefaultDeprecation(String x);

    abstract FeatureSet features();

    public abstract Builder setFeatures(FeatureSet x);

    @CanIgnoreReturnValue
    public final Builder mergeFeatures(FeatureSet x) {
      return setFeatures(FeatureSet.merge(features(), x));
    }

    public abstract Builder setLicense(License x);

    /** Note that we don't check dupes in this method. Check beforehand! */
    public abstract Builder setDefaultCompatibleWith(Iterable<Label> x);

    /** Note that we don't check dupes in this method. Check beforehand! */
    public abstract Builder setDefaultRestrictedTo(Iterable<Label> x);

    @Nullable
    abstract ImmutableList<Label> defaultPackageMetadata();

    /** Note that we don't check dupes in this method. Check beforehand! */
    public abstract Builder setDefaultPackageMetadata(List<Label> x);

    public abstract Builder setDefaultHdrsCheck(String x);

    public abstract PackageArgs build();
  }

  private static List<Label> throwIfHasDupes(List<Label> labels, String what) throws EvalException {
    var dupes = ImmutableSortedSet.copyOf(CollectionUtils.duplicatedElementsOf(labels));
    if (!dupes.isEmpty()) {
      throw Starlark.errorf("duplicate label(s) in %s: %s", what, Joiner.on(", ").join(dupes));
    }
    return labels;
  }

  /**
   * Processes the given Starlark parameter to the {@code package()/repo()} call into a field on a
   * {@link Builder} object.
   */
  public static void processParam(
      String name, Object rawValue, String what, LabelConverter labelConverter, Builder builder)
      throws EvalException {
    switch (name) {
      case "default_visibility":
        builder.setDefaultVisibility(
            RuleVisibility.parse(BuildType.LABEL_LIST.convert(rawValue, what, labelConverter)));
        break;
      case "default_testonly":
        builder.setDefaultTestOnly(Type.BOOLEAN.convert(rawValue, what, labelConverter));
        break;
      case "default_deprecation":
        builder.setDefaultDeprecation(Type.STRING.convert(rawValue, what, labelConverter));
        break;
      case "features":
        builder.mergeFeatures(
            FeatureSet.parse(Types.STRING_LIST.convert(rawValue, what, labelConverter)));
        break;
      case "licenses":
        builder.setLicense(BuildType.LICENSE.convert(rawValue, what, labelConverter));
        break;
      case "default_compatible_with":
        builder.setDefaultCompatibleWith(
            throwIfHasDupes(BuildType.LABEL_LIST.convert(rawValue, what, labelConverter), name));
        break;
      case "default_restricted_to":
        builder.setDefaultRestrictedTo(
            throwIfHasDupes(BuildType.LABEL_LIST.convert(rawValue, what, labelConverter), name));
        break;
      case "default_applicable_licenses":
      case "default_package_metadata":
        if (builder.defaultPackageMetadata() != null) {
          throw Starlark.errorf(
              "Can not set both default_package_metadata and default_applicable_licenses."
                  + " Move all declarations to default_package_metadata.");
        }
        builder.setDefaultPackageMetadata(
            throwIfHasDupes(BuildType.LABEL_LIST.convert(rawValue, what, labelConverter), name));
        break;
      case "default_hdrs_check":
        builder.setDefaultHdrsCheck(Type.STRING.convert(rawValue, what, labelConverter));
        break;
      default:
        throw Starlark.errorf("unexpected keyword argument: %s", name);
    }
  }

  /**
   * Returns a new {@link PackageArgs} containing the result of merging {@code other} into {@code
   * this}. {@code other}'s fields take precedence if specified.
   */
  public PackageArgs mergeWith(PackageArgs other) {
    Builder builder = toBuilder();
    if (other.defaultVisibility() != null) {
      builder.setDefaultVisibility(other.defaultVisibility());
    }
    if (other.defaultTestOnly() != null) {
      builder.setDefaultTestOnly(other.defaultTestOnly());
    }
    if (other.defaultDeprecation() != null) {
      builder.setDefaultDeprecation(other.defaultDeprecation());
    }
    if (!other.features().equals(FeatureSet.EMPTY)) {
      builder.mergeFeatures(other.features());
    }
    if (other.license() != null) {
      builder.setLicense(other.license());
    }
    if (other.defaultCompatibleWith() != null) {
      builder.setDefaultCompatibleWith(other.defaultCompatibleWith());
    }
    if (other.defaultRestrictedTo() != null) {
      builder.setDefaultRestrictedTo(other.defaultRestrictedTo());
    }
    if (other.defaultPackageMetadata() != null) {
      builder.setDefaultPackageMetadata(other.defaultPackageMetadata());
    }
    if (other.defaultHdrsCheck() != null) {
      builder.setDefaultHdrsCheck(other.defaultHdrsCheck());
    }
    return builder.build();
  }
}
