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

import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.bazel.BazelRepositoryModule;
import com.google.devtools.build.lib.bazel.bzlmod.BazelDepGraphFunction;
import com.google.devtools.build.lib.bazel.bzlmod.BazelLockFileFunction;
import com.google.devtools.build.lib.bazel.bzlmod.BazelModuleResolutionFunction;
import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileFunction;
import com.google.devtools.build.lib.bazel.bzlmod.RegistryFactory;
import com.google.devtools.build.lib.bazel.bzlmod.RegistryFactoryImpl;
import com.google.devtools.build.lib.bazel.bzlmod.YankedVersionsUtil;
import com.google.devtools.build.lib.bazel.repository.RepositoryOptions;
import com.google.devtools.build.lib.bazel.repository.cache.RepositoryCache;
import com.google.devtools.build.lib.bazel.repository.downloader.DownloadManager;
import com.google.devtools.build.lib.bazel.repository.downloader.HttpDownloader;
import com.google.devtools.build.lib.bazel.repository.starlark.StarlarkRepositoryFunction;
import com.google.devtools.build.lib.bazel.rules.BazelRulesModule;
import com.google.devtools.build.lib.packages.BuildFileName;
import com.google.devtools.build.lib.repository.ExternalPackageHelper;
import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction;
import com.google.devtools.build.lib.skyframe.ActionEnvironmentFunction;
import com.google.devtools.build.lib.skyframe.BazelSkyframeExecutorConstants;
import com.google.devtools.build.lib.skyframe.ClientEnvironmentFunction;
import com.google.devtools.build.lib.skyframe.DirectoryListingFunction;
import com.google.devtools.build.lib.skyframe.DirectoryListingStateFunction;
import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction;
import com.google.devtools.build.lib.skyframe.LocalRepositoryLookupFunction;
import com.google.devtools.build.lib.skyframe.PackageFunction.ActionOnIOExceptionReadingBuildFile;
import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy;
import com.google.devtools.build.lib.skyframe.PrecomputedValue;
import com.google.devtools.build.lib.skyframe.SkyFunctions;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.lib.vfs.SyscallCache;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Concrete implementation of {@link PackageLoader} that uses skyframe under the covers, but with no
 * caching or incrementality.
 */
public class BazelPackageLoader extends AbstractPackageLoader {
  private static final ImmutableList<BuildFileName> BUILD_FILES_BY_PRIORITY =
      BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY;

  private static final ExternalPackageHelper EXTERNAL_PACKAGE_HELPER =
      BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER;

  /** Returns a fresh {@link Builder} instance. */
  public static Builder builder(Root workspaceDir, Path installBase, Path outputBase) {
    // Prevent PackageLoader from fetching any remote repositories; these should only be fetched by
    // Bazel before calling PackageLoader.
    AtomicBoolean isFetch = new AtomicBoolean(false);
    return new Builder(workspaceDir, installBase, outputBase, isFetch);
  }

  /** Builder for {@link BazelPackageLoader} instances. */
  public static class Builder extends AbstractPackageLoader.Builder {
    private static final ConfiguredRuleClassProvider DEFAULT_RULE_CLASS_PROVIDER =
        createRuleClassProvider();

    private final AtomicBoolean isFetch;

    private static ConfiguredRuleClassProvider createRuleClassProvider() {
      ConfiguredRuleClassProvider.Builder classProvider = new ConfiguredRuleClassProvider.Builder();
      new BazelRepositoryModule().initializeRuleClasses(classProvider);
      new BazelRulesModule().initializeRuleClasses(classProvider);
      return classProvider.build();
    }

    private Builder(Root workspaceDir, Path installBase, Path outputBase, AtomicBoolean isFetch) {
      super(
          workspaceDir,
          installBase,
          outputBase,
          BUILD_FILES_BY_PRIORITY,
          ExternalFileAction.DEPEND_ON_EXTERNAL_PKG_FOR_EXTERNAL_REPO_PATHS);
      this.isFetch = isFetch;
      addExtraPrecomputedValues(
          PrecomputedValue.injected(PrecomputedValue.ACTION_ENV, ImmutableMap.of()),
          PrecomputedValue.injected(PrecomputedValue.REPO_ENV, ImmutableMap.of()),
          PrecomputedValue.injected(
              RepositoryDelegatorFunction.REPOSITORY_OVERRIDES,
              Suppliers.ofInstance(ImmutableMap.of())),
          PrecomputedValue.injected(
              RepositoryDelegatorFunction.RESOLVED_FILE_INSTEAD_OF_WORKSPACE, Optional.empty()),
          PrecomputedValue.injected(
              RepositoryDelegatorFunction.FORCE_FETCH,
              RepositoryDelegatorFunction.FORCE_FETCH_DISABLED),
          PrecomputedValue.injected(ModuleFileFunction.MODULE_OVERRIDES, ImmutableMap.of()),
          PrecomputedValue.injected(
              RepositoryDelegatorFunction.FORCE_FETCH_CONFIGURE,
              RepositoryDelegatorFunction.FORCE_FETCH_DISABLED),
          PrecomputedValue.injected(RepositoryDelegatorFunction.VENDOR_DIRECTORY, Optional.empty()),
          PrecomputedValue.injected(ModuleFileFunction.REGISTRIES, ImmutableList.of()),
          PrecomputedValue.injected(ModuleFileFunction.IGNORE_DEV_DEPS, false),
          PrecomputedValue.injected(
              BazelModuleResolutionFunction.CHECK_DIRECT_DEPENDENCIES,
              RepositoryOptions.CheckDirectDepsMode.OFF),
          PrecomputedValue.injected(
              BazelModuleResolutionFunction.BAZEL_COMPATIBILITY_MODE,
              RepositoryOptions.BazelCompatibilityMode.OFF),
          PrecomputedValue.injected(
              BazelLockFileFunction.LOCKFILE_MODE, RepositoryOptions.LockfileMode.OFF),
          PrecomputedValue.injected(
              YankedVersionsUtil.ALLOWED_YANKED_VERSIONS, ImmutableList.of()));
    }

    @Override
    public BazelPackageLoader buildImpl() {
      // Set up SkyFunctions and PrecomputedValues needed to make local repositories work correctly.
      RepositoryCache repositoryCache = new RepositoryCache();
      HttpDownloader httpDownloader = new HttpDownloader();
      DownloadManager downloadManager = new DownloadManager(repositoryCache, httpDownloader);
      RegistryFactory registryFactory =
          new RegistryFactoryImpl(
              directories.getWorkspace(), downloadManager, Suppliers.ofInstance(ImmutableMap.of()));

      // Allow tests to override SkyFunctions.MODULE_FILE to use fake registry
      if (!this.extraSkyFunctions.containsKey(SkyFunctions.MODULE_FILE)) {
        addExtraSkyFunctions(
            ImmutableMap.of(
                SkyFunctions.MODULE_FILE,
                new ModuleFileFunction(
                    ruleClassProvider.getBazelStarlarkEnvironment(),
                    registryFactory,
                    directories.getWorkspace(),
                    ImmutableMap.of())));
      }

      addExtraSkyFunctions(
          ImmutableMap.<SkyFunctionName, SkyFunction>builder()
              .put(
                  SkyFunctions.CLIENT_ENVIRONMENT_VARIABLE,
                  new ClientEnvironmentFunction(new AtomicReference<>(ImmutableMap.of())))
              .put(
                  SkyFunctions.DIRECTORY_LISTING_STATE,
                  new DirectoryListingStateFunction(externalFilesHelper, SyscallCache.NO_CACHE))
              .put(SkyFunctions.ACTION_ENVIRONMENT_VARIABLE, new ActionEnvironmentFunction())
              .put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction())
              .put(
                  SkyFunctions.LOCAL_REPOSITORY_LOOKUP,
                  new LocalRepositoryLookupFunction(EXTERNAL_PACKAGE_HELPER))
              .put(
                  SkyFunctions.REPOSITORY_DIRECTORY,
                  new RepositoryDelegatorFunction(
                      BazelRepositoryModule.repositoryRules(),
                      new StarlarkRepositoryFunction(downloadManager),
                      isFetch,
                      ImmutableMap::of,
                      directories,
                      EXTERNAL_PACKAGE_HELPER))
              .put(SkyFunctions.BAZEL_DEP_GRAPH, new BazelDepGraphFunction())
              .put(SkyFunctions.BAZEL_MODULE_RESOLUTION, new BazelModuleResolutionFunction())
              .buildOrThrow());

      return new BazelPackageLoader(this);
    }

    @Override
    protected ConfiguredRuleClassProvider getDefaultRuleClassProvider() {
      return DEFAULT_RULE_CLASS_PROVIDER;
    }

    @CanIgnoreReturnValue
    public Builder setFetchForTesting() {
      this.isFetch.set(true);
      return this;
    }
  }

  private BazelPackageLoader(Builder builder) {
    super(builder);
  }

  @Override
  protected CrossRepositoryLabelViolationStrategy getCrossRepositoryLabelViolationStrategy() {
    return BazelSkyframeExecutorConstants.CROSS_REPOSITORY_LABEL_VIOLATION_STRATEGY;
  }

  @Override
  protected ImmutableList<BuildFileName> getBuildFilesByPriority() {
    return BUILD_FILES_BY_PRIORITY;
  }

  @Override
  protected ExternalPackageHelper getExternalPackageHelper() {
    return EXTERNAL_PACKAGE_HELPER;
  }

  @Override
  protected ActionOnIOExceptionReadingBuildFile getActionOnIOExceptionReadingBuildFile() {
    return BazelSkyframeExecutorConstants.ACTION_ON_IO_EXCEPTION_READING_BUILD_FILE;
  }

  @Override
  protected boolean shouldUseRepoDotBazel() {
    return BazelSkyframeExecutorConstants.USE_REPO_DOT_BAZEL;
  }
}
