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

import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.cmdline.BazelStarlarkContext;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.Optional;
import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkThread;

/**
 * Bazel application data for the Starlark thread that evaluates the top-level code in a .bzl (or
 * .scl) module (i.e. when evaluating that module's global symbols).
 */
public final class BzlInitThreadContext extends BazelStarlarkContext
    implements RuleDefinitionEnvironment {

  private final Label bzlFile;

  /* Digest of the .bzl file being initialized along with all its transitive loads. */
  private final byte[] transitiveDigest;

  // For storing the result of calling `visibility()`.
  @Nullable private BzlVisibility bzlVisibility;

  private final RepositoryName toolsRepository;

  // TODO(b/192694287): Remove once we migrate all tests from the allowlist
  private final Optional<Label> networkAllowlistForTests;

  // Used for `configuration_field`.
  private final ImmutableMap<String, Class<?>> fragmentNameToClass;

  /**
   * Constructs a new context for initializing a .bzl file.
   *
   * @param bzlFile the name of the .bzl being initialized
   * @param transitiveDigest the hash of that file and its transitive load()s
   * @param toolsRepository the name of the tools repository, such as "@bazel_tools"
   * @param networkAllowlistForTests an allowlist for rule classes created by this thread
   * @param fragmentNameToClass a map from configuration fragment name to configuration fragment
   *     class, such as "apple" to AppleConfiguration.class
   * @param mainRepoMapping the repository mapping of the main repository
   */
  public BzlInitThreadContext(
      Label bzlFile,
      byte[] transitiveDigest,
      RepositoryName toolsRepository,
      Optional<Label> networkAllowlistForTests,
      ImmutableMap<String, Class<?>> fragmentNameToClass,
      RepositoryMapping mainRepoMapping) {
    super(BazelStarlarkContext.Phase.LOADING, () -> mainRepoMapping);
    this.bzlFile = bzlFile;
    this.transitiveDigest = transitiveDigest;
    this.toolsRepository = toolsRepository;
    this.networkAllowlistForTests = networkAllowlistForTests;
    this.fragmentNameToClass = fragmentNameToClass;
  }

  /**
   * Retrieves this context from a Starlark thread. If not present, throws {@code EvalException}
   * with an error message indicating that {@code what} can't be used in this Starlark environment.
   */
  @CanIgnoreReturnValue
  public static BzlInitThreadContext fromOrFail(StarlarkThread thread, String what)
      throws EvalException {
    @Nullable BazelStarlarkContext ctx = thread.getThreadLocal(BazelStarlarkContext.class);
    if (!(ctx instanceof BzlInitThreadContext)) {
      throw Starlark.errorf(
          "%s can only be used during .bzl initialization (top-level evaluation)", what);
    }
    return (BzlInitThreadContext) ctx;
  }

  /**
   * Returns the label of the .bzl module being initialized.
   *
   * <p>Note that this is not necessarily the same as the module of the innermost stack frame (i.e.,
   * {@code BazelModuleContext.of(Module.ofInnermostEnclosingStarlarkFunction(thread)).label()}),
   * since the module may call helper functions loaded from elsewhere.
   */
  public Label getBzlFile() {
    return bzlFile;
  }

  /** Returns the transitive digest of the .bzl module being initialized. */
  public byte[] getTransitiveDigest() {
    return transitiveDigest;
  }

  /**
   * Returns the saved BzlVisibility that was declared for the currently initializing .bzl module.
   */
  @Nullable
  public BzlVisibility getBzlVisibility() {
    return bzlVisibility;
  }

  /** Sets the BzlVisibility for the currently initializing .bzl module. */
  public void setBzlVisibility(BzlVisibility bzlVisibility) {
    this.bzlVisibility = bzlVisibility;
  }

  /** Returns the name of the tools repository, such as "@bazel_tools". */
  @Override
  public RepositoryName getToolsRepository() {
    return toolsRepository;
  }

  /** Returns a label for network allowlist for tests if one should be added. */
  // TODO(b/192694287): Remove once we migrate all tests from the allowlist.
  @Override
  public Optional<Label> getNetworkAllowlistForTests() {
    return networkAllowlistForTests;
  }

  /** Returns a map from configuration fragment name to configuration fragment class. */
  public ImmutableMap<String, Class<?>> getFragmentNameToClass() {
    return fragmentNameToClass;
  }
}
