// Copyright 2020 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.collect.ImmutableMap;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationConstant;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import net.starlark.java.eval.StarlarkSemantics;

/**
 * A Skyframe value representing the result of evaluating the {@code @_builtins} pseudo-repository.
 *
 * <p>To avoid unnecessary Skyframe edges, the {@code StarlarkSemantics} are included in this value,
 * so that a caller who obtains a StarlarkBuiltinsValue can also access the StarlarkSemantics
 * without an additional dependency.
 *
 * <p>These are parsed from {@code @_builtins//:exports.bzl}.
 */
public final class StarlarkBuiltinsValue implements SkyValue {

  static final String BUILTINS_NAME = "_builtins";

  /**
   * The builtins pseudo-repository.
   *
   * <p>It is illegal to declare a repository in WORKSPACE whose name collides with this one.
   * Whether a collision has in fact occurred is determined by {@link RepositoryName#equals}, and
   * hence depends on the OS path policy (i.e. the case sensitivity of the host system).
   *
   * <p>Regardless of path policy, all actual uses of the builtins pseudo-repo are case sensitive
   * and must match {@link #BUILTINS_NAME} exactly.
   */
  // TODO(#11437): Add actual enforcement that users cannot define a repo named "@_builtins".
  @SerializationConstant
  static final RepositoryName BUILTINS_REPO = RepositoryName.createUnvalidated(BUILTINS_NAME);

  /** Reports whether the given repository is the special builtins pseudo-repository. */
  static boolean isBuiltinsRepo(RepositoryName repo) {
    // Use String.equals(), not RepositoryName.equals(), to force case sensitivity.
    return repo.getName().equals(BUILTINS_NAME);
  }

  // These are all (except transitiveDigest) deeply immutable since the Starlark values are already
  // frozen, so let's skip the accessors and mutators.

  /**
   * Top-level predeclared symbols for a .bzl file loaded on behalf of a BUILD file, after builtins
   * injection has been applied.
   */
  public final ImmutableMap<String, Object> predeclaredForBuildBzl;

  /**
   * Top-level predeclared symbols for a .bzl file loaded on behalf of a WORKSPACE file after
   * builtins injection has been applied.
   */
  public final ImmutableMap<String, Object> predeclaredForWorkspaceBzl;

  /**
   * Top-level predeclared symbols for a BUILD file, after builtins injection but before any prelude
   * file has been applied.
   */
  public final ImmutableMap<String, Object> predeclaredForBuild;

  /** Contents of the {@code exported_to_java} dict. */
  public final ImmutableMap<String, Object> exportedToJava;

  /** Transitive digest of all .bzl files in {@code @_builtins}. */
  public final byte[] transitiveDigest;

  /** The StarlarkSemantics used for {@code @_builtins} evaluation. */
  public final StarlarkSemantics starlarkSemantics;

  private StarlarkBuiltinsValue(
      ImmutableMap<String, Object> predeclaredForBuildBzl,
      ImmutableMap<String, Object> predeclaredForWorkspaceBzl,
      ImmutableMap<String, Object> predeclaredForBuild,
      ImmutableMap<String, Object> exportedToJava,
      byte[] transitiveDigest,
      StarlarkSemantics starlarkSemantics) {
    this.predeclaredForBuildBzl = predeclaredForBuildBzl;
    this.predeclaredForWorkspaceBzl = predeclaredForWorkspaceBzl;
    this.predeclaredForBuild = predeclaredForBuild;
    this.exportedToJava = exportedToJava;
    this.transitiveDigest = transitiveDigest;
    this.starlarkSemantics = starlarkSemantics;
  }

  public static StarlarkBuiltinsValue create(
      ImmutableMap<String, Object> predeclaredForBuildBzl,
      ImmutableMap<String, Object> predeclaredForWorkspaceBzl,
      ImmutableMap<String, Object> predeclaredForBuild,
      ImmutableMap<String, Object> exportedToJava,
      byte[] transitiveDigest,
      StarlarkSemantics starlarkSemantics) {
    return new StarlarkBuiltinsValue(
        predeclaredForBuildBzl,
        predeclaredForWorkspaceBzl,
        predeclaredForBuild,
        exportedToJava,
        transitiveDigest,
        starlarkSemantics);
  }

  /**
   * Constructs a placeholder builtins value to be used when builtins injection is disabled, or for
   * use within builtins evaluation itself.
   *
   * <p>The placeholder simply wraps the StarlarkSemantics object. This lets code paths that don't
   * use injection still conveniently access the semantics without incurring a separate Skyframe
   * edge.
   */
  public static StarlarkBuiltinsValue createEmpty(StarlarkSemantics starlarkSemantics) {
    return new StarlarkBuiltinsValue(
        /* predeclaredForBuildBzl= */ ImmutableMap.of(),
        /* predeclaredForWorkspaceBzl= */ ImmutableMap.of(),
        /* predeclaredForBuild= */ ImmutableMap.of(),
        /* exportedToJava= */ ImmutableMap.of(),
        /* transitiveDigest= */ new byte[] {},
        starlarkSemantics);
  }

  /** Returns the singleton SkyKey for this type of value. */
  public static Key key() {
    return Key.INSTANCE;
  }

  /**
   * Skyframe key for retrieving the {@code @_builtins} definitions.
   *
   * <p>This has no fields since there is only one {@code StarlarkBuiltinsValue} at a time.
   */
  static final class Key implements SkyKey {

    private static final Key INSTANCE = new Key();

    private Key() {}

    @Override
    public SkyFunctionName functionName() {
      return SkyFunctions.STARLARK_BUILTINS;
    }

    @Override
    public String toString() {
      return "Starlark @_builtins";
    }

    @Override
    public boolean equals(Object other) {
      return other instanceof Key;
    }

    @Override
    public int hashCode() {
      return 7727; // more or less xkcd/221
    }
  }
}
