// 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 static com.google.common.collect.ImmutableSortedMap.toImmutableSortedMap;
import static java.util.Comparator.naturalOrder;

import com.google.auto.value.AutoValue;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.Comparators;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.bazel.bzlmod.InterimModule.DepSpec;
import com.google.devtools.build.lib.server.FailureDetails.ExternalDeps.Code;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.function.Function;
import javax.annotation.Nullable;

/**
 * Runs module selection. This step of module resolution reads the output of {@link Discovery} and
 * applies the Minimal Version Selection algorithm to it, removing unselected modules from the
 * dependency graph and rewriting dependencies to point to the selected versions. It also returns an
 * un-pruned version of the dep graph for inspection purpose.
 *
 * <p>Essentially, what needs to happen is:
 *
 * <ul>
 *   <li>In the most basic case, only one version of each module is selected (ie. remains in the dep
 *       graph). The selected version is simply the highest among all existing versions in the dep
 *       graph. In other words, each module name forms a "selection group". If foo@1.5 is selected,
 *       then any other foo@X is removed from the dep graph, and any module depending on foo@X will
 *       depend on foo@1.5 instead.
 *   <li>As an extension of the above, we also remove any module that becomes unreachable from the
 *       root module because of the removal of some other module.
 *   <li>If, however, versions of the same module but with different compatibility levels exist in
 *       the dep graph, then one version is selected for each compatibility level (ie. we split the
 *       selection groups by compatibility level). In the end, though, still only one version can
 *       remain in the dep graph after the removal of unselected and unreachable modules.
 *   <li>Things get more complicated with multiple-version overrides. If module foo has a
 *       multiple-version override which allows versions [1.3, 1.5, 2.0] (using the major version as
 *       the compatibility level), then we further split the selection groups by the target allowed
 *       version (keep in mind that versions are upgraded to the nearest higher-or-equal allowed
 *       version at the same compatibility level). If, for example, some module depends on foo@1.0,
 *       then it'll depend on foo@1.3 post-selection instead (and foo@1.0 will be removed). If any
 *       of foo@1.7, foo@2.2, or foo@3.0 exist in the dependency graph before selection, they must
 *       be removed before the end of selection (by becoming unreachable, for example), otherwise
 *       it'll be an error since they're not allowed by the override (these versions are in
 *       selection groups that have no valid target allowed version).
 *   <li>Things get even more complicated with max_compatibility_level. The difference this
 *       introduces is that each "DepSpec" could be satisfied by one of multiple choices. (Without
 *       max_compatibility_level, there is always only one choice.) So what we do is go through all
 *       the combinations of possible choices for each distinct DepSpec, and for each combination,
 *       see if the resulting dep graph is valid. As soon as we find a valid combination, we return
 *       that result. The distinct DepSpecs are sorted by the order they first appear in the dep
 *       graph if we BFS from the root module. The combinations are attempted in the typical
 *       cartesian product order (see {@link Lists#cartesianProduct}); the "version choices" of each
 *       DepSpec are sorted from low to high.
 * </ul>
 */
final class Selection {
  private Selection() {}

  /** The result of selection. */
  @AutoValue
  abstract static class Result {
    /** Final dep graph sorted in BFS iteration order, with unused modules removed. */
    abstract ImmutableMap<ModuleKey, InterimModule> getResolvedDepGraph();

    /**
     * Un-pruned dep graph, with updated dep keys, and additionally containing the unused modules
     * which were initially discovered (and their MODULE.bazel files loaded). Does not contain
     * modules overridden by {@code single_version_override} or {@link NonRegistryOverride}, only by
     * {@code multiple_version_override}.
     */
    abstract ImmutableMap<ModuleKey, InterimModule> getUnprunedDepGraph();

    static Result create(
        ImmutableMap<ModuleKey, InterimModule> resolvedDepGraph,
        ImmutableMap<ModuleKey, InterimModule> unprunedDepGraph) {
      return new AutoValue_Selection_Result(resolvedDepGraph, unprunedDepGraph);
    }
  }

  /** During selection, a version is selected for each distinct "selection group". */
  @AutoValue
  abstract static class SelectionGroup {
    static SelectionGroup create(
        String moduleName, int compatibilityLevel, Version targetAllowedVersion) {
      return new AutoValue_Selection_SelectionGroup(
          moduleName, compatibilityLevel, targetAllowedVersion);
    }

    abstract String getModuleName();

    abstract int getCompatibilityLevel();

    /** This is only used for modules with multiple-version overrides. */
    abstract Version getTargetAllowedVersion();
  }

  @AutoValue
  abstract static class ModuleNameAndCompatibilityLevel {
    static ModuleNameAndCompatibilityLevel create(String moduleName, int compatibilityLevel) {
      return new AutoValue_Selection_ModuleNameAndCompatibilityLevel(
          moduleName, compatibilityLevel);
    }

    abstract String getModuleName();

    abstract int getCompatibilityLevel();
  }

  /**
   * Computes a mapping from (moduleName, compatibilityLevel) to the set of allowed versions. This
   * is only performed for modules with multiple-version overrides.
   */
  private static ImmutableMap<ModuleNameAndCompatibilityLevel, ImmutableSortedSet<Version>>
      computeAllowedVersionSets(
          ImmutableMap<String, ModuleOverride> overrides,
          ImmutableMap<ModuleKey, InterimModule> depGraph)
          throws ExternalDepsException {
    Map<ModuleNameAndCompatibilityLevel, ImmutableSortedSet.Builder<Version>> allowedVersionSets =
        new HashMap<>();
    for (Map.Entry<String, ModuleOverride> overrideEntry : overrides.entrySet()) {
      String moduleName = overrideEntry.getKey();
      ModuleOverride override = overrideEntry.getValue();
      if (!(override instanceof MultipleVersionOverride)) {
        continue;
      }
      ImmutableList<Version> allowedVersions = ((MultipleVersionOverride) override).getVersions();
      for (Version allowedVersion : allowedVersions) {
        InterimModule allowedVersionModule =
            depGraph.get(ModuleKey.create(moduleName, allowedVersion));
        if (allowedVersionModule == null) {
          throw ExternalDepsException.withMessage(
              Code.VERSION_RESOLUTION_ERROR,
              "multiple_version_override for module %s contains version %s, but it doesn't"
                  + " exist in the dependency graph",
              moduleName,
              allowedVersion);
        }
        ImmutableSortedSet.Builder<Version> allowedVersionSet =
            allowedVersionSets.computeIfAbsent(
                ModuleNameAndCompatibilityLevel.create(
                    moduleName, allowedVersionModule.getCompatibilityLevel()),
                // Remember that the empty version compares greater than any other version, so we
                // can use it as a sentinel value.
                k -> ImmutableSortedSet.<Version>naturalOrder().add(Version.EMPTY));
        allowedVersionSet.add(allowedVersion);
      }
    }
    return ImmutableMap.copyOf(
        Maps.transformValues(allowedVersionSets, ImmutableSortedSet.Builder::build));
  }

  /**
   * Computes the {@link SelectionGroup} for the given module. If the module has a multiple-version
   * override (which would be reflected in the allowedVersionSets), information in there will be
   * used to compute its targetAllowedVersion.
   */
  private static SelectionGroup computeSelectionGroup(
      InterimModule module,
      ImmutableMap<ModuleNameAndCompatibilityLevel, ImmutableSortedSet<Version>>
          allowedVersionSets) {
    ImmutableSortedSet<Version> allowedVersionSet =
        allowedVersionSets.get(
            ModuleNameAndCompatibilityLevel.create(
                module.getName(), module.getCompatibilityLevel()));
    if (allowedVersionSet == null) {
      // This means that this module has no multiple-version override.
      return SelectionGroup.create(
          module.getKey().getName(), module.getCompatibilityLevel(), Version.EMPTY);
    }
    return SelectionGroup.create(
        module.getKey().getName(),
        module.getCompatibilityLevel(),
        // We use the `ceiling` method here to quickly locate the lowest allowed version that's
        // still no lower than this module's version.
        // If this module's version is higher than any allowed version (in which case EMPTY is
        // returned), it should result in an error. We don't immediately throw here because it might
        // still become unreferenced later.
        allowedVersionSet.ceiling(module.getVersion()));
  }

  /**
   * Computes the possible list of ModuleKeys a single given DepSpec can resolve to. This is
   * normally just one ModuleKey, but when max_compatibility_level is involved, multiple choices may
   * be possible.
   */
  private static ImmutableList<ModuleKey> computePossibleResolutionResultsForOneDepSpec(
      DepSpec depSpec,
      ImmutableMap<ModuleKey, SelectionGroup> selectionGroups,
      Map<SelectionGroup, Version> selectedVersions) {
    int minCompatibilityLevel = selectionGroups.get(depSpec.toModuleKey()).getCompatibilityLevel();
    int maxCompatibilityLevel =
        depSpec.getMaxCompatibilityLevel() < 0
            ? minCompatibilityLevel
            : depSpec.getMaxCompatibilityLevel();
    // First find the selection groups that this DepSpec could use.
    return Maps.filterKeys(
            selectedVersions,
            group ->
                group.getModuleName().equals(depSpec.getName())
                    && group.getCompatibilityLevel() >= minCompatibilityLevel
                    && group.getCompatibilityLevel() <= maxCompatibilityLevel
                    && group.getTargetAllowedVersion().compareTo(depSpec.getVersion()) >= 0)
        .entrySet()
        .stream()
        // Collect into an ImmutableSortedMap so that:
        //  1. The final list is sorted by compatibility level, guaranteeing lowest version first;
        //  2. Only one ModuleKey is attempted per compatibility level, so that in the case of a
        //     multiple-version override, we only try the lowest allowed version in that
        //     compatibility level (note the Comparators::min call).
        .collect(
            toImmutableSortedMap(
                naturalOrder(),
                e -> e.getKey().getCompatibilityLevel(),
                e -> e.getValue(),
                Comparators::min))
        .values()
        .stream()
        .map(v -> ModuleKey.create(depSpec.getName(), v))
        .collect(toImmutableList());
  }

  /**
   * Computes the possible list of ModuleKeys a DepSpec can resolve to, for all distinct DepSpecs in
   * the dependency graph.
   */
  private static ImmutableMap<DepSpec, ImmutableList<ModuleKey>> computePossibleResolutionResults(
      ImmutableMap<ModuleKey, InterimModule> depGraph,
      ImmutableMap<ModuleKey, SelectionGroup> selectionGroups,
      Map<SelectionGroup, Version> selectedVersions) {
    // Important that we use a LinkedHashMap here to ensure reproducibility.
    Map<DepSpec, ImmutableList<ModuleKey>> results = new LinkedHashMap<>();
    for (InterimModule module : depGraph.values()) {
      for (DepSpec depSpec : module.getDeps().values()) {
        results.computeIfAbsent(
            depSpec,
            ds ->
                computePossibleResolutionResultsForOneDepSpec(
                    ds, selectionGroups, selectedVersions));
      }
    }
    return ImmutableMap.copyOf(results);
  }

  /**
   * Given the possible list of ModuleKeys each DepSpec can resolve to, enumerate through all the
   * possible resolution strategies. Each strategy assigns each DepSpec to a single ModuleKey out of
   * its possible list.
   */
  private static List<Function<DepSpec, ModuleKey>> enumerateStrategies(
      ImmutableMap<DepSpec, ImmutableList<ModuleKey>> possibleResolutionResults) {
    Map<DepSpec, Integer> depSpecToPosition = new HashMap<>();
    int position = 0;
    for (DepSpec depSpec : possibleResolutionResults.keySet()) {
      depSpecToPosition.put(depSpec, position++);
    }
    return Lists.transform(
        Lists.cartesianProduct(possibleResolutionResults.values().asList()),
        (List<ModuleKey> choices) ->
            (DepSpec depSpec) -> choices.get(depSpecToPosition.get(depSpec)));
    // TODO(wyv): There are some strategies that we could eliminate earlier. For example, the
    //   strategy where (foo@1.1, maxCL=3) resolves to foo@2.0 and (foo@1.2, maxCL=3) resolves to
    //   foo@3.0 is obviously not valid. All foo@? should resolve to the same version (assuming no
    //   multiple-version override).
  }

  /** Runs module selection (aka version resolution). */
  public static Result run(
      ImmutableMap<ModuleKey, InterimModule> depGraph,
      ImmutableMap<String, ModuleOverride> overrides)
      throws ExternalDepsException {
    // For any multiple-version overrides, build a mapping from (moduleName, compatibilityLevel) to
    // the set of allowed versions.
    ImmutableMap<ModuleNameAndCompatibilityLevel, ImmutableSortedSet<Version>> allowedVersionSets =
        computeAllowedVersionSets(overrides, depGraph);

    // For each module in the dep graph, pre-compute its selection group. For most modules this is
    // simply its (moduleName, compatibilityLevel) tuple; for modules with multiple-version
    // overrides, it additionally includes the targetAllowedVersion, which denotes the version to
    // "snap" to during selection.
    ImmutableMap<ModuleKey, SelectionGroup> selectionGroups =
        ImmutableMap.copyOf(
            Maps.transformValues(
                depGraph, module -> computeSelectionGroup(module, allowedVersionSets)));

    // Figure out the version to select for every selection group.
    Map<SelectionGroup, Version> selectedVersions = new HashMap<>();
    for (Map.Entry<ModuleKey, SelectionGroup> entry : selectionGroups.entrySet()) {
      ModuleKey key = entry.getKey();
      SelectionGroup selectionGroup = entry.getValue();
      selectedVersions.merge(selectionGroup, key.getVersion(), Comparators::max);
    }

    // Compute the possible list of ModuleKeys that each DepSpec could resolve to.
    ImmutableMap<DepSpec, ImmutableList<ModuleKey>> possibleResolutionResults =
        computePossibleResolutionResults(depGraph, selectionGroups, selectedVersions);
    for (Map.Entry<DepSpec, ImmutableList<ModuleKey>> e : possibleResolutionResults.entrySet()) {
      if (e.getValue().isEmpty()) {
        throw ExternalDepsException.withMessage(
            Code.VERSION_RESOLUTION_ERROR,
            "Unexpected error: %s has no valid resolution result",
            e.getKey());
      }
    }

    // Each DepSpec may resolve to one or more ModuleKeys. We try out every single possible
    // combination; in other words, we enumerate through the cartesian product of the "possible
    // resolution result" set for every distinct DepSpec. Each element of this cartesian product is
    // essentially a mapping from DepSpecs to ModuleKeys; we can call this mapping a "resolution
    // strategy".
    //
    // Given a resolution strategy, we can walk through the graph from the root module, and see if
    // the strategy yields a valid graph (only containing the nodes reachable from the root). If the
    // graph is invalid (for example, because there are modules with different compatibility
    // levels), we try the next resolution strategy. When all strategies are exhausted, we know
    // there is no way to achieve a valid selection result, so we report the failure from the time
    // we attempted to walk the graph using the first resolution strategy.
    DepGraphWalker depGraphWalker = new DepGraphWalker(depGraph, overrides, selectionGroups);
    ExternalDepsException firstFailure = null;
    for (Function<DepSpec, ModuleKey> resolutionStrategy :
        enumerateStrategies(possibleResolutionResults)) {
      try {
        ImmutableMap<ModuleKey, InterimModule> prunedDepGraph =
            depGraphWalker.walk(resolutionStrategy);
        // If the call above didn't throw, we have a valid graph. Go ahead and produce a result!
        ImmutableMap<ModuleKey, InterimModule> unprunedDepGraph =
            ImmutableMap.copyOf(
                Maps.transformValues(
                    depGraph,
                    module ->
                        module.withDepSpecsTransformed(
                            depSpec -> DepSpec.fromModuleKey(resolutionStrategy.apply(depSpec)))));
        return Result.create(prunedDepGraph, unprunedDepGraph);
      } catch (ExternalDepsException e) {
        if (firstFailure == null) {
          firstFailure = e;
        }
      }
    }
    // firstFailure cannot be null, since enumerateStrategies(...) cannot be empty, since no
    // element of possibleResolutionResults is empty.
    throw firstFailure;
  }

  /**
   * Walks the dependency graph from the root node, collecting any reachable nodes through deps into
   * a new dep graph and checking that nothing conflicts.
   */
  static class DepGraphWalker {
    private static final Joiner JOINER = Joiner.on(", ");
    private final ImmutableMap<ModuleKey, InterimModule> oldDepGraph;
    private final ImmutableMap<String, ModuleOverride> overrides;
    private final ImmutableMap<ModuleKey, SelectionGroup> selectionGroups;

    DepGraphWalker(
        ImmutableMap<ModuleKey, InterimModule> oldDepGraph,
        ImmutableMap<String, ModuleOverride> overrides,
        ImmutableMap<ModuleKey, SelectionGroup> selectionGroups) {
      this.oldDepGraph = oldDepGraph;
      this.overrides = overrides;
      this.selectionGroups = selectionGroups;
    }

    /**
     * Walks the old dep graph and builds a new dep graph containing only deps reachable from the
     * root module. The returned map has a guaranteed breadth-first iteration order.
     */
    ImmutableMap<ModuleKey, InterimModule> walk(Function<DepSpec, ModuleKey> resolutionStrategy)
        throws ExternalDepsException {
      HashMap<String, ExistingModule> moduleByName = new HashMap<>();
      ImmutableMap.Builder<ModuleKey, InterimModule> newDepGraph = ImmutableMap.builder();
      Set<ModuleKey> known = new HashSet<>();
      Queue<ModuleKeyAndDependent> toVisit = new ArrayDeque<>();
      toVisit.add(ModuleKeyAndDependent.create(ModuleKey.ROOT, null));
      known.add(ModuleKey.ROOT);
      while (!toVisit.isEmpty()) {
        ModuleKeyAndDependent moduleKeyAndDependent = toVisit.remove();
        ModuleKey key = moduleKeyAndDependent.getModuleKey();
        InterimModule module =
            oldDepGraph
                .get(key)
                .withDepSpecsTransformed(
                    depSpec -> DepSpec.fromModuleKey(resolutionStrategy.apply(depSpec)));
        visit(key, module, moduleKeyAndDependent.getDependent(), moduleByName);

        for (DepSpec depSpec : module.getDeps().values()) {
          if (known.add(depSpec.toModuleKey())) {
            toVisit.add(ModuleKeyAndDependent.create(depSpec.toModuleKey(), key));
          }
        }
        newDepGraph.put(key, module);
      }
      return newDepGraph.buildOrThrow();
    }

    void visit(
        ModuleKey key,
        InterimModule module,
        @Nullable ModuleKey from,
        HashMap<String, ExistingModule> moduleByName)
        throws ExternalDepsException {
      ModuleOverride override = overrides.get(key.getName());
      if (override instanceof MultipleVersionOverride) {
        if (selectionGroups.get(key).getTargetAllowedVersion().isEmpty()) {
          // This module has no target allowed version, which means that there's no allowed version
          // higher than its version at the same compatibility level.
          Preconditions.checkState(
              from != null, "the root module cannot have a multiple version override");
          throw ExternalDepsException.withMessage(
              Code.VERSION_RESOLUTION_ERROR,
              "%s depends on %s which is not allowed by the multiple_version_override on %s,"
                  + " which allows only [%s]",
              from,
              key,
              key.getName(),
              JOINER.join(((MultipleVersionOverride) override).getVersions()));
        }
      } else {
        ExistingModule existingModuleWithSameName =
            moduleByName.put(
                module.getName(), ExistingModule.create(key, module.getCompatibilityLevel(), from));
        if (existingModuleWithSameName != null) {
          // This has to mean that a module with the same name but a different compatibility level
          // was also selected.
          Preconditions.checkState(
              from != null && existingModuleWithSameName.getDependent() != null,
              "the root module cannot possibly exist more than once in the dep graph");
          throw ExternalDepsException.withMessage(
              Code.VERSION_RESOLUTION_ERROR,
              "%s depends on %s with compatibility level %d, but %s depends on %s with"
                  + " compatibility level %d which is different",
              from,
              key,
              module.getCompatibilityLevel(),
              existingModuleWithSameName.getDependent(),
              existingModuleWithSameName.getModuleKey(),
              existingModuleWithSameName.getCompatibilityLevel());
        }
      }

      // Make sure that we don't have `module` depending on the same dependency version twice.
      HashMap<ModuleKey, String> depKeyToRepoName = new HashMap<>();
      for (Map.Entry<String, DepSpec> depEntry : module.getDeps().entrySet()) {
        String repoName = depEntry.getKey();
        DepSpec depSpec = depEntry.getValue();
        String previousRepoName = depKeyToRepoName.put(depSpec.toModuleKey(), repoName);
        if (previousRepoName != null) {
          throw ExternalDepsException.withMessage(
              Code.VERSION_RESOLUTION_ERROR,
              "%s depends on %s at least twice (with repo names %s and %s). Consider adding a"
                  + " multiple_version_override if you want to depend on multiple versions of"
                  + " %s simultaneously",
              key,
              depSpec.toModuleKey(),
              repoName,
              previousRepoName,
              key.getName());
        }
      }
    }

    @AutoValue
    abstract static class ModuleKeyAndDependent {
      abstract ModuleKey getModuleKey();

      @Nullable
      abstract ModuleKey getDependent();

      static ModuleKeyAndDependent create(ModuleKey moduleKey, @Nullable ModuleKey dependent) {
        return new AutoValue_Selection_DepGraphWalker_ModuleKeyAndDependent(moduleKey, dependent);
      }
    }

    @AutoValue
    abstract static class ExistingModule {
      abstract ModuleKey getModuleKey();

      abstract int getCompatibilityLevel();

      @Nullable
      abstract ModuleKey getDependent();

      static ExistingModule create(
          ModuleKey moduleKey, int compatibilityLevel, ModuleKey dependent) {
        return new AutoValue_Selection_DepGraphWalker_ExistingModule(
            moduleKey, compatibilityLevel, dependent);
      }
    }
  }
}
