// 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 com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.docgen.annot.DocumentMethods;
import com.google.devtools.build.lib.bazel.bzlmod.InterimModule.DepSpec;
import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileGlobals.ModuleExtensionUsageBuilder.ModuleExtensionProxy;
import com.google.devtools.build.lib.bazel.bzlmod.Version.ParseException;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.StarlarkExportable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import net.starlark.java.annot.Param;
import net.starlark.java.annot.ParamType;
import net.starlark.java.annot.StarlarkBuiltin;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.Dict;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkInt;
import net.starlark.java.eval.StarlarkThread;
import net.starlark.java.eval.StarlarkValue;
import net.starlark.java.eval.Structure;
import net.starlark.java.eval.Tuple;
import net.starlark.java.syntax.Location;

/** A collection of global Starlark build API functions that apply to MODULE.bazel files. */
@DocumentMethods
public class ModuleFileGlobals {

  /* Valid bazel compatibility argument must 1) start with (<,<=,>,>=,-);
     2) then contain a version number in form of X.X.X where X has one or two digits
  */
  private static final Pattern VALID_BAZEL_COMPATIBILITY_VERSION =
      Pattern.compile("(>|<|-|<=|>=)(\\d+\\.){2}\\d+");

  private boolean moduleCalled = false;
  private boolean hadNonModuleCall = false;
  private final boolean ignoreDevDeps;
  private final InterimModule.Builder module;
  private final ImmutableMap<String, NonRegistryOverride> builtinModules;
  private final Map<String, DepSpec> deps = new LinkedHashMap<>();
  private final List<ModuleExtensionUsageBuilder> extensionUsageBuilders = new ArrayList<>();
  private final Map<String, ModuleOverride> overrides = new HashMap<>();
  private final Map<String, RepoNameUsage> repoNameUsages = new HashMap<>();

  public ModuleFileGlobals(
      ImmutableMap<String, NonRegistryOverride> builtinModules,
      ModuleKey key,
      @Nullable Registry registry,
      boolean ignoreDevDeps) {
    module = InterimModule.builder().setKey(key).setRegistry(registry);
    this.ignoreDevDeps = ignoreDevDeps;
    this.builtinModules = builtinModules;
  }

  @AutoValue
  abstract static class RepoNameUsage {
    abstract String getHow();

    abstract Location getWhere();
  }

  private void addRepoNameUsage(String repoName, String how, Location where) throws EvalException {
    RepoNameUsage collision =
        repoNameUsages.put(repoName, new AutoValue_ModuleFileGlobals_RepoNameUsage(how, where));
    if (collision != null) {
      throw Starlark.errorf(
          "The repo name '%s' is already being used %s at %s",
          repoName, collision.getHow(), collision.getWhere());
    }
  }

  @VisibleForTesting
  static void validateModuleName(String moduleName) throws EvalException {
    if (!RepositoryName.VALID_MODULE_NAME.matcher(moduleName).matches()) {
      throw Starlark.errorf(
          "invalid module name '%s': valid names must 1) only contain lowercase letters (a-z),"
              + " digits (0-9), dots (.), hyphens (-), and underscores (_); 2) begin with a"
              + " lowercase letter; 3) end with a lowercase letter or digit.",
          moduleName);
    }
  }

  @StarlarkMethod(
      name = "module",
      doc =
          "Declares certain properties of the Bazel module represented by the current Bazel repo."
              + " These properties are either essential metadata of the module (such as the name"
              + " and version), or affect behavior of the current module and its dependents.  <p>It"
              + " should be called at most once. It can be omitted only if this module is the root"
              + " module (as in, if it's not going to be depended on by another module).",
      parameters = {
        @Param(
            name = "name",
            doc =
                "The name of the module. Can be omitted only if this module is the root module (as"
                    + " in, if it's not going to be depended on by another module). A valid module"
                    + " name must: 1) only contain lowercase letters (a-z), digits (0-9), dots (.),"
                    + " hyphens (-), and underscores (_); 2) begin with a lowercase letter; 3) end"
                    + " with a lowercase letter or digit.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "version",
            // TODO(wyv): explain version format
            doc =
                "The version of the module. Can be omitted only if this module is the root module"
                    + " (as in, if it's not going to be depended on by another module).",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "compatibility_level",
            // TODO(wyv): See X for more details
            doc =
                "The compatibility level of the module; this should be changed every time a major"
                    + " incompatible change is introduced. This is essentially the \"major"
                    + " version\" of the module in terms of SemVer, except that it's not embedded"
                    + " in the version string itself, but exists as a separate field. Modules with"
                    + " different compatibility levels participate in version resolution as if"
                    + " they're modules with different names, but the final dependency graph"
                    + " cannot contain multiple modules with the same name but different"
                    + " compatibility levels (unless <code>multiple_version_override</code> is in"
                    + " effect; see there for more details).",
            named = true,
            positional = false,
            defaultValue = "0"),
        @Param(
            name = "repo_name",
            doc =
                "The name of the repository representing this module, as seen by the module itself."
                    + " By default, the name of the repo is the name of the module. This can be"
                    + " specified to ease migration for projects that have been using a repo name"
                    + " for itself that differs from its module name.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "bazel_compatibility",
            doc =
                "A list of bazel versions that allows users to declare which Bazel versions"
                    + " are compatible with this module. It does NOT affect dependency resolution,"
                    + " but bzlmod will use this information to check if your current Bazel version"
                    + " is compatible. The format of this value is a string of some constraint"
                    + " values separated by comma. Three constraints are supported: <=X.X.X: The"
                    + " Bazel version must be equal or older than X.X.X. Used when there is a known"
                    + " incompatible change in a newer version. >=X.X.X: The Bazel version must be"
                    + " equal or newer than X.X.X.Used when you depend on some features that are"
                    + " only available since X.X.X. -X.X.X: The Bazel version X.X.X is not"
                    + " compatible. Used when there is a bug in X.X.X that breaks you, but fixed in"
                    + " later versions.",
            named = true,
            positional = false,
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            defaultValue = "[]"),
      },
      useStarlarkThread = true)
  public void module(
      String name,
      String version,
      StarlarkInt compatibilityLevel,
      String repoName,
      Iterable<?> bazelCompatibility,
      StarlarkThread thread)
      throws EvalException {
    if (moduleCalled) {
      throw Starlark.errorf("the module() directive can only be called once");
    }
    if (hadNonModuleCall) {
      throw Starlark.errorf("if module() is called, it must be called before any other functions");
    }
    moduleCalled = true;
    if (!name.isEmpty()) {
      validateModuleName(name);
    }
    if (repoName.isEmpty()) {
      repoName = name;
      addRepoNameUsage(name, "as the current module name", thread.getCallerLocation());
    } else {
      RepositoryName.validateUserProvidedRepoName(repoName);
      addRepoNameUsage(repoName, "as the module's own repo name", thread.getCallerLocation());
    }
    Version parsedVersion;
    try {
      parsedVersion = Version.parse(version);
    } catch (ParseException e) {
      throw new EvalException("Invalid version in module()", e);
    }
    module
        .setName(name)
        .setVersion(parsedVersion)
        .setCompatibilityLevel(compatibilityLevel.toInt("compatibility_level"))
        .addBazelCompatibilityValues(
            checkAllCompatibilityVersions(bazelCompatibility, "bazel_compatibility"))
        .setRepoName(repoName);
  }

  private static ImmutableList<String> checkAllAbsolutePatterns(Iterable<?> iterable, String where)
      throws EvalException {
    Sequence<String> list = Sequence.cast(iterable, String.class, where);
    for (String item : list) {
      if (!item.startsWith("//") && !item.startsWith("@")) {
        throw Starlark.errorf(
            "Expected absolute target patterns (must begin with '//' or '@') for '%s' argument, but"
                + " got '%s' as an argument",
            where, item);
      }
    }
    return list.getImmutableList();
  }

  private static ImmutableList<String> checkAllCompatibilityVersions(
      Iterable<?> iterable, String where) throws EvalException {
    Sequence<String> list = Sequence.cast(iterable, String.class, where);
    for (String version : list) {
      if (!VALID_BAZEL_COMPATIBILITY_VERSION.matcher(version).matches()) {
        throw Starlark.errorf(
            "invalid version argument '%s': valid argument must 1) start with (<,<=,>,>=,-); "
                + "2) contain a version number in form of X.X.X where X is a number",
            version);
      }
    }
    return list.getImmutableList();
  }

  @StarlarkMethod(
      name = "bazel_dep",
      doc = "Declares a direct dependency on another Bazel module.",
      parameters = {
        @Param(
            name = "name",
            doc = "The name of the module to be added as a direct dependency.",
            named = true,
            positional = false),
        @Param(
            name = "version",
            doc = "The version of the module to be added as a direct dependency.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "max_compatibility_level",
            doc =
                "The maximum <code>compatibility_level</code> supported for the module to be added"
                    + " as a direct dependency. The version of the module implies the minimum"
                    + " compatibility_level supported, as well as the maximum if this attribute is"
                    + " not specified.",
            named = true,
            positional = false,
            defaultValue = "-1"),
        @Param(
            name = "repo_name",
            doc =
                "The name of the external repo representing this dependency. This is by default the"
                    + " name of the module.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "dev_dependency",
            doc =
                "If true, this dependency will be ignored if the current module is not the root"
                    + " module or `--ignore_dev_dependency` is enabled.",
            named = true,
            positional = false,
            defaultValue = "False"),
      },
      useStarlarkThread = true)
  public void bazelDep(
      String name,
      String version,
      StarlarkInt maxCompatibilityLevel,
      String repoName,
      boolean devDependency,
      StarlarkThread thread)
      throws EvalException {
    hadNonModuleCall = true;
    if (repoName.isEmpty()) {
      repoName = name;
    }
    validateModuleName(name);
    Version parsedVersion;
    try {
      parsedVersion = Version.parse(version);
    } catch (ParseException e) {
      throw new EvalException("Invalid version in bazel_dep()", e);
    }
    RepositoryName.validateUserProvidedRepoName(repoName);

    if (!(ignoreDevDeps && devDependency)) {
      deps.put(
          repoName,
          DepSpec.create(
              name, parsedVersion, maxCompatibilityLevel.toInt("max_compatibility_level")));
    }

    addRepoNameUsage(repoName, "by a bazel_dep", thread.getCallerLocation());
  }

  @StarlarkMethod(
      name = "register_execution_platforms",
      doc =
          "Specifies already-defined execution platforms to be registered when this module is"
              + " selected. Should be absolute target patterns (ie. beginning with either"
              + " <code>@</code> or <code>//</code>). See <a href=\"${link toolchains}\">toolchain"
              + " resolution</a> for more information.",
      parameters = {
        @Param(
            name = "dev_dependency",
            doc =
                "If true, the execution platforms will not be registered if the current module is"
                    + " not the root module or `--ignore_dev_dependency` is enabled.",
            named = true,
            positional = false,
            defaultValue = "False"),
      },
      extraPositionals =
          @Param(
              name = "platform_labels",
              allowedTypes = {@ParamType(type = Sequence.class, generic1 = String.class)},
              doc = "The labels of the platforms to register."))
  public void registerExecutionPlatforms(boolean devDependency, Sequence<?> platformLabels)
      throws EvalException {
    hadNonModuleCall = true;
    if (ignoreDevDeps && devDependency) {
      return;
    }
    module.addExecutionPlatformsToRegister(
        checkAllAbsolutePatterns(platformLabels, "register_execution_platforms"));
  }

  @StarlarkMethod(
      name = "register_toolchains",
      doc =
          "Specifies already-defined toolchains to be registered when this module is selected."
              + " Should be absolute target patterns (ie. beginning with either <code>@</code> or"
              + " <code>//</code>). See <a href=\"${link toolchains}\">toolchain resolution</a> for"
              + " more information.",
      parameters = {
        @Param(
            name = "dev_dependency",
            doc =
                "If true, the toolchains will not be registered if the current module is not the"
                    + " root module or `--ignore_dev_dependency` is enabled.",
            named = true,
            positional = false,
            defaultValue = "False"),
      },
      extraPositionals =
          @Param(
              name = "toolchain_labels",
              allowedTypes = {@ParamType(type = Sequence.class, generic1 = String.class)},
              doc = "The labels of the toolchains to register."))
  public void registerToolchains(boolean devDependency, Sequence<?> toolchainLabels)
      throws EvalException {
    hadNonModuleCall = true;
    if (ignoreDevDeps && devDependency) {
      return;
    }
    module.addToolchainsToRegister(
        checkAllAbsolutePatterns(toolchainLabels, "register_toolchains"));
  }

  @StarlarkMethod(
      name = "use_extension",
      doc =
          "Returns a proxy object representing a module extension; its methods can be invoked to"
              + " create module extension tags.",
      parameters = {
        @Param(
            name = "extension_bzl_file",
            doc = "A label to the Starlark file defining the module extension."),
        @Param(
            name = "extension_name",
            doc =
                "The name of the module extension to use. A symbol with this name must be exported"
                    + " by the Starlark file."),
        @Param(
            name = "dev_dependency",
            doc =
                "If true, this usage of the module extension will be ignored if the current module"
                    + " is not the root module or `--ignore_dev_dependency` is enabled.",
            named = true,
            positional = false,
            defaultValue = "False"),
        @Param(
            name = "isolate",
            doc =
                "If true, this usage of the module extension will be isolated from all other "
                    + "usages, both in this and other modules. Tags created for this usage do not "
                    + "affect other usages and the repositories generated by the extension for "
                    + "this usage will be distinct from all other repositories generated by the "
                    + "extension."
                    + "<p>This parameter is currently experimental and only available with the "
                    + "flag <code>--experimental_isolated_extension_usages</code>.",
            named = true,
            positional = false,
            defaultValue = "False",
            enableOnlyWithFlag = "-experimental_isolated_extension_usages",
            valueWhenDisabled = "False"),
      },
      useStarlarkThread = true)
  public ModuleExtensionProxy useExtension(
      String rawExtensionBzlFile,
      String extensionName,
      boolean devDependency,
      boolean isolate,
      StarlarkThread thread) {
    hadNonModuleCall = true;

    String extensionBzlFile = normalizeLabelString(rawExtensionBzlFile);
    ModuleExtensionUsageBuilder newUsageBuilder =
        new ModuleExtensionUsageBuilder(
            extensionBzlFile, extensionName, isolate, thread.getCallerLocation());

    if (ignoreDevDeps && devDependency) {
      // This is a no-op proxy.
      return newUsageBuilder.getProxy(devDependency);
    }

    // Find an existing usage builder corresponding to this extension. Isolated usages need to get
    // their own proxy.
    if (!isolate) {
      for (ModuleExtensionUsageBuilder usageBuilder : extensionUsageBuilders) {
        if (usageBuilder.extensionBzlFile.equals(extensionBzlFile)
            && usageBuilder.extensionName.equals(extensionName)
            && !usageBuilder.isolate) {
          return usageBuilder.getProxy(devDependency);
        }
      }
    }

    // If no such proxy exists, we can just use a new one.
    extensionUsageBuilders.add(newUsageBuilder);
    return newUsageBuilder.getProxy(devDependency);
  }

  private String normalizeLabelString(String rawExtensionBzlFile) {
    // Normalize the label by adding the current module's repo_name if the label doesn't specify a
    // repository name. This is necessary as ModuleExtensionUsages are grouped by the string value
    // of this label, but later mapped to their Label representation. If multiple strings map to the
    // same Label, this would result in a crash.
    // ownName can't change anymore as calling module() after this results in an error.
    String ownName = module.getRepoName().orElse(module.getName());
    if (module.getKey().equals(ModuleKey.ROOT) && rawExtensionBzlFile.startsWith("@//")) {
      return "@" + ownName + rawExtensionBzlFile.substring(1);
    } else if (rawExtensionBzlFile.startsWith("//")) {
      return "@" + ownName + rawExtensionBzlFile;
    } else {
      return rawExtensionBzlFile;
    }
  }

  class ModuleExtensionUsageBuilder {
    private final String extensionBzlFile;
    private final String extensionName;
    private final boolean isolate;
    private final Location location;
    private final HashBiMap<String, String> imports;
    private final ImmutableSet.Builder<String> devImports;
    private final ImmutableList.Builder<Tag> tags;

    private boolean hasNonDevUseExtension;
    private boolean hasDevUseExtension;
    private String exportedName;

    ModuleExtensionUsageBuilder(
        String extensionBzlFile, String extensionName, boolean isolate, Location location) {
      this.extensionBzlFile = extensionBzlFile;
      this.extensionName = extensionName;
      this.isolate = isolate;
      this.location = location;
      this.imports = HashBiMap.create();
      this.devImports = ImmutableSet.builder();
      this.tags = ImmutableList.builder();
    }

    ModuleExtensionUsage buildUsage() throws EvalException {
      var builder =
          ModuleExtensionUsage.builder()
              .setExtensionBzlFile(extensionBzlFile)
              .setExtensionName(extensionName)
              .setUsingModule(module.getKey())
              .setLocation(location)
              .setImports(ImmutableBiMap.copyOf(imports))
              .setDevImports(devImports.build())
              .setHasDevUseExtension(hasDevUseExtension)
              .setHasNonDevUseExtension(hasNonDevUseExtension)
              .setTags(tags.build());
      if (isolate) {
        if (exportedName == null) {
          throw Starlark.errorf(
              "Isolated extension usage at %s must be assigned to a top-level variable", location);
        }
        builder.setIsolationKey(
            Optional.of(ModuleExtensionId.IsolationKey.create(module.getKey(), exportedName)));
      } else {
        builder.setIsolationKey(Optional.empty());
      }
      return builder.build();
    }

    /**
     * Creates a proxy with the specified dev_dependency bit that shares accumulated imports and
     * tags with all other such proxies, thus preserving their order across dev/non-dev deps.
     */
    ModuleExtensionProxy getProxy(boolean devDependency) {
      if (devDependency) {
        hasDevUseExtension = true;
      } else {
        hasNonDevUseExtension = true;
      }
      return new ModuleExtensionProxy(devDependency);
    }

    @StarlarkBuiltin(name = "module_extension_proxy", documented = false)
    class ModuleExtensionProxy implements Structure, StarlarkExportable {

      private final boolean devDependency;

      private ModuleExtensionProxy(boolean devDependency) {
        this.devDependency = devDependency;
      }

      void addImport(String localRepoName, String exportedName, Location location)
          throws EvalException {
        RepositoryName.validateUserProvidedRepoName(localRepoName);
        RepositoryName.validateUserProvidedRepoName(exportedName);
        addRepoNameUsage(localRepoName, "by a use_repo() call", location);
        if (imports.containsValue(exportedName)) {
          String collisionRepoName = imports.inverse().get(exportedName);
          throw Starlark.errorf(
              "The repo exported as '%s' by module extension '%s' is already imported at %s",
              exportedName, extensionName, repoNameUsages.get(collisionRepoName).getWhere());
        }
        imports.put(localRepoName, exportedName);
        if (devDependency) {
          devImports.add(exportedName);
        }
      }

      @Nullable
      @Override
      public Object getValue(String tagName) throws EvalException {
        return new StarlarkValue() {
          @StarlarkMethod(
              name = "call",
              selfCall = true,
              documented = false,
              extraKeywords = @Param(name = "kwargs"),
              useStarlarkThread = true)
          public void call(Dict<String, Object> kwargs, StarlarkThread thread) {
            tags.add(
                Tag.builder()
                    .setTagName(tagName)
                    .setAttributeValues(AttributeValues.create(kwargs))
                    .setDevDependency(devDependency)
                    .setLocation(thread.getCallerLocation())
                    .build());
          }
        };
      }

      @Override
      public ImmutableCollection<String> getFieldNames() {
        return ImmutableList.of();
      }

      @Nullable
      @Override
      public String getErrorMessageForUnknownField(String field) {
        return null;
      }

      @Override
      public boolean isExported() {
        return exportedName != null;
      }

      @Override
      public void export(EventHandler handler, Label bzlFileLabel, String name) {
        exportedName = name;
      }
    }
  }

  @StarlarkMethod(
      name = "use_repo",
      doc =
          "Imports one or more repos generated by the given module extension into the scope of the"
              + " current module.",
      parameters = {
        @Param(
            name = "extension_proxy",
            doc = "A module extension proxy object returned by a <code>use_extension</code> call."),
      },
      extraPositionals = @Param(name = "args", doc = "The names of the repos to import."),
      extraKeywords =
          @Param(
              name = "kwargs",
              doc =
                  "Specifies certain repos to import into the scope of the current module with"
                      + " different names. The keys should be the name to use in the current scope,"
                      + " whereas the values should be the original names exported by the module"
                      + " extension."),
      useStarlarkThread = true)
  public void useRepo(
      ModuleExtensionProxy extensionProxy,
      Tuple args,
      Dict<String, Object> kwargs,
      StarlarkThread thread)
      throws EvalException {
    hadNonModuleCall = true;
    Location location = thread.getCallerLocation();
    for (String arg : Sequence.cast(args, String.class, "args")) {
      extensionProxy.addImport(arg, arg, location);
    }
    for (Map.Entry<String, String> entry :
        Dict.cast(kwargs, String.class, String.class, "kwargs").entrySet()) {
      extensionProxy.addImport(entry.getKey(), entry.getValue(), location);
    }
  }

  private void addOverride(String moduleName, ModuleOverride override) throws EvalException {
    validateModuleName(moduleName);
    ModuleOverride existingOverride = overrides.putIfAbsent(moduleName, override);
    if (existingOverride != null) {
      throw Starlark.errorf("multiple overrides for dep %s found", moduleName);
    }
  }

  @StarlarkMethod(
      name = "single_version_override",
      doc =
          "Specifies that a dependency should still come from a registry, but its version should"
              + " be pinned, or its registry overridden, or a list of patches applied. This"
              + " directive only takes effect in the root module; in other words, if a module"
              + " is used as a dependency by others, its own overrides are ignored.",
      parameters = {
        @Param(
            name = "module_name",
            doc = "The name of the Bazel module dependency to apply this override to.",
            named = true,
            positional = false),
        @Param(
            name = "version",
            doc =
                "Overrides the declared version of this module in the dependency graph. In other"
                    + " words, this module will be \"pinned\" to this override version. This"
                    + " attribute can be omitted if all one wants to override is the registry or"
                    + " the patches. ",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "registry",
            doc =
                "Overrides the registry for this module; instead of finding this module from the"
                    + " default list of registries, the given registry should be used.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "patches",
            doc =
                "A list of labels pointing to patch files to apply for this module. The patch files"
                    + " must exist in the source tree of the top level project. They are applied in"
                    + " the list order.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_cmds",
            doc =
                "Sequence of Bash commands to be applied on Linux/Macos after patches are applied.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_strip",
            doc = "Same as the --strip argument of Unix patch.",
            named = true,
            positional = false,
            defaultValue = "0"),
      })
  public void singleVersionOverride(
      String moduleName,
      String version,
      String registry,
      Iterable<?> patches,
      Iterable<?> patchCmds,
      StarlarkInt patchStrip)
      throws EvalException {
    hadNonModuleCall = true;
    Version parsedVersion;
    try {
      parsedVersion = Version.parse(version);
    } catch (ParseException e) {
      throw new EvalException("Invalid version in single_version_override()", e);
    }
    addOverride(
        moduleName,
        SingleVersionOverride.create(
            parsedVersion,
            registry,
            Sequence.cast(patches, String.class, "patches").getImmutableList(),
            Sequence.cast(patchCmds, String.class, "patchCmds").getImmutableList(),
            patchStrip.toInt("single_version_override.patch_strip")));
  }

  @StarlarkMethod(
      name = "multiple_version_override",
      doc =
          "Specifies that a dependency should still come from a registry, but multiple versions of"
              + " it should be allowed to coexist. See <a"
              + " href=\"/external/module#multiple-version_override\">the documentation</a> for"
              + " more details. This"
              + " directive only takes effect in the root module; in other words, if a module"
              + " is used as a dependency by others, its own overrides are ignored.",
      parameters = {
        @Param(
            name = "module_name",
            doc = "The name of the Bazel module dependency to apply this override to.",
            named = true,
            positional = false),
        @Param(
            name = "versions",
            // TODO(wyv): See X for more details
            doc =
                "Explicitly specifies the versions allowed to coexist. These versions must already"
                    + " be present in the dependency graph pre-selection. Dependencies on this"
                    + " module will be \"upgraded\" to the nearest higher allowed version at the"
                    + " same compatibility level, whereas dependencies that have a higher version"
                    + " than any allowed versions at the same compatibility level will cause an"
                    + " error.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false),
        @Param(
            name = "registry",
            doc =
                "Overrides the registry for this module; instead of finding this module from the"
                    + " default list of registries, the given registry should be used.",
            named = true,
            positional = false,
            defaultValue = "''"),
      })
  public void multipleVersionOverride(String moduleName, Iterable<?> versions, String registry)
      throws EvalException {
    hadNonModuleCall = true;
    ImmutableList.Builder<Version> parsedVersionsBuilder = new ImmutableList.Builder<>();
    try {
      for (String version : Sequence.cast(versions, String.class, "versions").getImmutableList()) {
        parsedVersionsBuilder.add(Version.parse(version));
      }
    } catch (ParseException e) {
      throw new EvalException("Invalid version in multiple_version_override()", e);
    }
    ImmutableList<Version> parsedVersions = parsedVersionsBuilder.build();
    if (parsedVersions.size() < 2) {
      throw new EvalException("multiple_version_override() must specify at least 2 versions");
    }
    addOverride(moduleName, MultipleVersionOverride.create(parsedVersions, registry));
  }

  @StarlarkMethod(
      name = "archive_override",
      doc =
          "Specifies that this dependency should come from an archive file (zip, gzip, etc) at a"
              + " certain location, instead of from a registry. This"
              + " directive only takes effect in the root module; in other words, if a module"
              + " is used as a dependency by others, its own overrides are ignored.",
      parameters = {
        @Param(
            name = "module_name",
            doc = "The name of the Bazel module dependency to apply this override to.",
            named = true,
            positional = false),
        @Param(
            name = "urls",
            allowedTypes = {
              @ParamType(type = String.class),
              @ParamType(type = Iterable.class, generic1 = String.class),
            },
            doc = "The URLs of the archive; can be http(s):// or file:// URLs.",
            named = true,
            positional = false),
        @Param(
            name = "integrity",
            doc = "The expected checksum of the archive file, in Subresource Integrity format.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "strip_prefix",
            doc = "A directory prefix to strip from the extracted files.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "patches",
            doc =
                "A list of labels pointing to patch files to apply for this module. The patch files"
                    + " must exist in the source tree of the top level project. They are applied in"
                    + " the list order.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_cmds",
            doc =
                "Sequence of Bash commands to be applied on Linux/Macos after patches are applied.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_strip",
            doc = "Same as the --strip argument of Unix patch.",
            named = true,
            positional = false,
            defaultValue = "0"),
      })
  public void archiveOverride(
      String moduleName,
      Object urls,
      String integrity,
      String stripPrefix,
      Iterable<?> patches,
      Iterable<?> patchCmds,
      StarlarkInt patchStrip)
      throws EvalException {
    hadNonModuleCall = true;
    ImmutableList<String> urlList =
        urls instanceof String
            ? ImmutableList.of((String) urls)
            : Sequence.cast(urls, String.class, "urls").getImmutableList();
    addOverride(
        moduleName,
        ArchiveOverride.create(
            urlList,
            Sequence.cast(patches, String.class, "patches").getImmutableList(),
            Sequence.cast(patchCmds, String.class, "patchCmds").getImmutableList(),
            integrity,
            stripPrefix,
            patchStrip.toInt("archive_override.patch_strip")));
  }

  @StarlarkMethod(
      name = "git_override",
      doc =
          "Specifies that a dependency should come from a certain commit of a Git repository. This"
              + " directive only takes effect in the root module; in other words, if a module"
              + " is used as a dependency by others, its own overrides are ignored.",
      parameters = {
        @Param(
            name = "module_name",
            doc = "The name of the Bazel module dependency to apply this override to.",
            named = true,
            positional = false),
        @Param(
            name = "remote",
            doc = "The URL of the remote Git repository.",
            named = true,
            positional = false),
        @Param(
            name = "commit",
            doc = "The commit that should be checked out.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "patches",
            doc =
                "A list of labels pointing to patch files to apply for this module. The patch files"
                    + " must exist in the source tree of the top level project. They are applied in"
                    + " the list order.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_cmds",
            doc =
                "Sequence of Bash commands to be applied on Linux/Macos after patches are applied.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_strip",
            doc = "Same as the --strip argument of Unix patch.",
            named = true,
            positional = false,
            defaultValue = "0"),
      })
  public void gitOverride(
      String moduleName,
      String remote,
      String commit,
      Iterable<?> patches,
      Iterable<?> patchCmds,
      StarlarkInt patchStrip)
      throws EvalException {
    hadNonModuleCall = true;
    addOverride(
        moduleName,
        GitOverride.create(
            remote,
            commit,
            Sequence.cast(patches, String.class, "patches").getImmutableList(),
            Sequence.cast(patchCmds, String.class, "patchCmds").getImmutableList(),
            patchStrip.toInt("git_override.patch_strip")));
  }

  @StarlarkMethod(
      name = "local_path_override",
      doc =
          "Specifies that a dependency should come from a certain directory on local disk. This"
              + " directive only takes effect in the root module; in other words, if a module"
              + " is used as a dependency by others, its own overrides are ignored.",
      parameters = {
        @Param(
            name = "module_name",
            doc = "The name of the Bazel module dependency to apply this override to.",
            named = true,
            positional = false),
        @Param(
            name = "path",
            doc = "The path to the directory where this module is.",
            named = true,
            positional = false),
      })
  public void localPathOverride(String moduleName, String path) throws EvalException {
    hadNonModuleCall = true;
    addOverride(moduleName, LocalPathOverride.create(path));
  }

  public InterimModule buildModule() throws EvalException {
    // Add builtin modules as default deps of the current module.
    for (String builtinModule : builtinModules.keySet()) {
      if (module.getKey().getName().equals(builtinModule)) {
        // The built-in module does not depend on itself.
        continue;
      }
      deps.put(builtinModule, DepSpec.create(builtinModule, Version.EMPTY, -1));
      try {
        addRepoNameUsage(builtinModule, "as a built-in dependency", Location.BUILTIN);
      } catch (EvalException e) {
        throw new EvalException(
            e.getMessage()
                + String.format(
                    ", '%s' is a built-in dependency and cannot be used by any 'bazel_dep' or"
                        + " 'use_repo' directive",
                    builtinModule),
            e);
      }
    }
    // Build module extension usages and the rest of the module.
    var extensionUsages = ImmutableList.<ModuleExtensionUsage>builder();
    for (var extensionUsageBuilder : extensionUsageBuilders) {
      extensionUsages.add(extensionUsageBuilder.buildUsage());
    }
    return module
        .setDeps(ImmutableMap.copyOf(deps))
        .setOriginalDeps(ImmutableMap.copyOf(deps))
        .setExtensionUsages(extensionUsages.build())
        .build();
  }

  public ImmutableMap<String, ModuleOverride> buildOverrides() {
    // Add overrides for builtin modules if there is no existing override for them.
    if (ModuleKey.ROOT.equals(module.getKey())) {
      for (String moduleName : builtinModules.keySet()) {
        overrides.putIfAbsent(moduleName, builtinModules.get(moduleName));
      }
    }
    return ImmutableMap.copyOf(overrides);
  }
}
