// Copyright 2021 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.bazel.bzlmod;

import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.ryanharter.auto.value.gson.GenerateTypeAdapter;
import java.util.Map;
import java.util.Optional;
import net.starlark.java.syntax.Location;

/**
 * Represents one usage of a module extension in one MODULE.bazel file. This class records all the
 * information pertinent to the proxy object returned from the {@code use_extension} call.
 *
 * <p>When adding new fields, make sure to update {@link #trimForEvaluation()} as well.
 */
@AutoValue
@GenerateTypeAdapter
public abstract class ModuleExtensionUsage {
  /** An unresolved label pointing to the Starlark file where the module extension is defined. */
  public abstract String getExtensionBzlFile();

  /** The name of the extension. */
  public abstract String getExtensionName();

  /**
   * The isolation key of this module extension usage. This is present if and only if the usage is
   * created with {@code isolate = True}.
   */
  public abstract Optional<ModuleExtensionId.IsolationKey> getIsolationKey();

  /** The module that contains this particular extension usage. */
  public abstract ModuleKey getUsingModule();

  /**
   * The location where this proxy object was created (by the {@code use_extension} call). Note that
   * if there were multiple {@code use_extension} calls on same extension, then this only stores the
   * location of the first one.
   */
  public abstract Location getLocation();

  /**
   * All the repos imported from this module extension into the scope of the current module. The key
   * is the local repo name (in the scope of the current module), and the value is the name exported
   * by the module extension.
   */
  public abstract ImmutableBiMap<String, String> getImports();

  /**
   * The repo names as exported by the module extension that were imported using a proxy marked as a
   * dev dependency.
   */
  public abstract ImmutableSet<String> getDevImports();

  /** All the tags specified by this module for this extension. */
  public abstract ImmutableList<Tag> getTags();

  /**
   * Whether any <code>use_extension</code> calls for this usage had <code>dev_dependency = True
   * </code> set.*
   */
  public abstract boolean getHasDevUseExtension();

  /**
   * Whether any <code>use_extension</code> calls for this usage had <code>dev_dependency = False
   * </code> set.*
   */
  public abstract boolean getHasNonDevUseExtension();

  public abstract Builder toBuilder();

  public static Builder builder() {
    return new AutoValue_ModuleExtensionUsage.Builder();
  }

  /**
   * Turns the given collection of usages for a particular extension into an object that can be
   * compared for equality with another object obtained in this way and compares equal only if the
   * two original collections of usages are equivalent for the purpose of evaluating the extension.
   */
  static ImmutableList<Map.Entry<ModuleKey, ModuleExtensionUsage>> trimForEvaluation(
      ImmutableMap<ModuleKey, ModuleExtensionUsage> usages) {
    // ImmutableMap#equals doesn't compare the order of entries, but it matters for the evaluation
    // of the extension.
    return ImmutableList.copyOf(
        Maps.transformValues(usages, ModuleExtensionUsage::trimForEvaluation).entrySet());
  }

  /**
   * Returns a new usage with all information removed that does not influence the evaluation of the
   * extension.
   */
  private ModuleExtensionUsage trimForEvaluation() {
    // We start with the full usage and selectively remove information that does not influence the
    // evaluation of the extension. Compared to explicitly copying over the parts that do, this
    // preserves correctness in case new fields are added without updating this code.
    return toBuilder()
        .setTags(getTags().stream().map(Tag::trimForEvaluation).collect(toImmutableList()))
        // Locations are only used for error reporting and thus don't influence whether the
        // evaluation of the extension is successful and what its result is in case of success.
        .setLocation(Location.BUILTIN)
        // Extension implementation functions do not see the imports, they are only validated
        // against the set of generated repos in a validation step that comes afterward.
        .setImports(ImmutableBiMap.of())
        .setDevImports(ImmutableSet.of())
        .build();
  }

  /** Builder for {@link ModuleExtensionUsage}. */
  @AutoValue.Builder
  public abstract static class Builder {

    public abstract Builder setExtensionBzlFile(String value);

    public abstract Builder setExtensionName(String value);

    public abstract Builder setIsolationKey(Optional<ModuleExtensionId.IsolationKey> value);

    public abstract Builder setUsingModule(ModuleKey value);

    public abstract Builder setLocation(Location value);

    public abstract Builder setImports(ImmutableBiMap<String, String> value);

    public abstract Builder setDevImports(ImmutableSet<String> value);

    public abstract Builder setTags(ImmutableList<Tag> value);

    abstract ImmutableList.Builder<Tag> tagsBuilder();

    @CanIgnoreReturnValue
    public ModuleExtensionUsage.Builder addTag(Tag value) {
      tagsBuilder().add(value);
      return this;
    }

    public abstract Builder setHasDevUseExtension(boolean hasDevUseExtension);

    public abstract Builder setHasNonDevUseExtension(boolean hasNonDevUseExtension);

    public abstract ModuleExtensionUsage build();
  }
}
