// 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.skyframe;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.bazel.bzlmod.Module;
import com.google.devtools.build.lib.bazel.bzlmod.ModuleKey;
import com.google.devtools.build.lib.bazel.bzlmod.SelectionValue;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;

/** {@link SkyFunction} for {@link RepositoryMappingValue}s. */
public class RepositoryMappingFunction implements SkyFunction {

  @Nullable
  @Override
  public SkyValue compute(SkyKey skyKey, Environment env)
      throws SkyFunctionException, InterruptedException {
    RepositoryName repositoryName = (RepositoryName) skyKey.argument();

    SelectionValue selectionValue = null;
    if (Preconditions.checkNotNull(RepositoryDelegatorFunction.ENABLE_BZLMOD.get(env))) {
      selectionValue = (SelectionValue) env.getValue(SelectionValue.KEY);
      if (env.valuesMissing()) {
        return null;
      }

      Optional<ImmutableMap<RepositoryName, RepositoryName>> mapping =
          computeFromBzlmod(repositoryName, selectionValue);
      if (mapping.isPresent()) {
        return RepositoryMappingValue.withMapping(mapping.get());
      }
    }

    SkyKey externalPackageKey = PackageValue.key(LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER);
    PackageValue externalPackageValue = (PackageValue) env.getValue(externalPackageKey);
    if (env.valuesMissing()) {
      return null;
    }

    return computeFromWorkspace(repositoryName, externalPackageValue, selectionValue);
  }

  /**
   * Calculate repo mappings for Bzlmod generated repository.
   *
   * @return the repo mappings for the repo if it's generated by Bzlmod, otherwise return
   *     Optional.empty().
   */
  private Optional<ImmutableMap<RepositoryName, RepositoryName>> computeFromBzlmod(
      RepositoryName repositoryName, SelectionValue selectionValue) {
    ModuleKey moduleKey =
        repositoryName.isMain()
            ? ModuleKey.ROOT
            : selectionValue.getCanonicalRepoNameLookup().get(repositoryName.strippedName());
    if (moduleKey == null) {
      return Optional.empty();
    }
    Module module = selectionValue.getDepGraph().get(moduleKey);
    ImmutableMap.Builder<RepositoryName, RepositoryName> repoMapping = ImmutableMap.builder();
    // module.getDeps() contains a mapping of Bazel module dependencies from the required repo name
    // to the module key. Go through them to construct the repo mappings.
    for (Map.Entry<String, ModuleKey> dep : module.getDeps().entrySet()) {
      String expectedRepoName = dep.getKey();
      String canonicalRepoName = dep.getValue().getCanonicalRepoName();
      if (expectedRepoName.equals(canonicalRepoName)) {
        continue;
      }
      // Special note: if `dep` is actually the root module, its ModuleKey would be ROOT whose
      // canonicalRepoName is the empty string. This perfectly maps to the main repo ("@").
      repoMapping.put(
          RepositoryName.createFromValidStrippedName(expectedRepoName),
          RepositoryName.createFromValidStrippedName(canonicalRepoName));
    }
    return Optional.of(repoMapping.build());
  }

  private SkyValue computeFromWorkspace(
      RepositoryName repositoryName,
      PackageValue externalPackageValue,
      @Nullable SelectionValue selectionValue)
      throws RepositoryMappingFunctionException {
    Package externalPackage = externalPackageValue.getPackage();
    if (externalPackage.containsErrors()) {
      throw new RepositoryMappingFunctionException();
    }
    if (selectionValue == null) {
      return RepositoryMappingValue.withMapping(
          externalPackage.getRepositoryMapping(repositoryName));
    }
    // If bzlmod is in play, we need to transform mappings to "foo" into mappings for "foo.1.3" (if
    // there is a module called "foo" in the dep graph and its version is 1.3, that is).
    ImmutableMap<String, ModuleKey> moduleNameLookup = selectionValue.getModuleNameLookup();
    HashMap<RepositoryName, RepositoryName> mapping = new HashMap<>();
    mapping.putAll(
        Maps.transformValues(
            externalPackage.getRepositoryMapping(repositoryName),
            toRepo -> {
              if (toRepo.isMain()) {
                return toRepo;
              }
              ModuleKey moduleKey = moduleNameLookup.get(toRepo.strippedName());
              return moduleKey == null
                  ? toRepo
                  : RepositoryName.createFromValidStrippedName(moduleKey.getCanonicalRepoName());
            }));
    // If there's no existing mapping to "foo", we should add a mapping from "foo" to "foo.1.3"
    // anyways.
    for (Map.Entry<String, ModuleKey> entry : moduleNameLookup.entrySet()) {
      mapping.putIfAbsent(
          RepositoryName.createFromValidStrippedName(entry.getKey()),
          RepositoryName.createFromValidStrippedName(entry.getValue().getCanonicalRepoName()));
    }
    return RepositoryMappingValue.withMapping(ImmutableMap.copyOf(mapping));
  }

  @Nullable
  @Override
  public String extractTag(SkyKey skyKey) {
    return null;
  }

  private static class RepositoryMappingFunctionException extends SkyFunctionException {
    RepositoryMappingFunctionException() {
      super(
          new BuildFileContainsErrorsException(LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER),
          Transience.PERSISTENT);
    }
  }
}
