// Copyright 2019 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 net.starlark.java.eval;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import net.starlark.java.syntax.Resolver;

/**
 * A {@link Module} represents a Starlark module, a container of global variables populated by
 * executing a Starlark file. Each top-level assignment updates a global variable in the module.
 *
 * <p>Each module references its "predeclared" environment, which is often shared among many
 * modules. These are the names that are defined even at the start of execution. For example, in
 * Bazel, the predeclared environment of the module for a BUILD or .bzl file defines name values
 * such as cc_binary and glob.
 *
 * <p>The predeclared environment implicitly includes the "universal" names present in every
 * Starlark thread in every dialect, such as None, len, and str; see {@link Starlark#UNIVERSE}.
 *
 * <p>Global bindings in a Module may shadow bindings inherited from the predeclared block.
 *
 * <p>A module may carry an arbitrary piece of client data. In Bazel, for example, the client data
 * records the module's build label (such as "//dir:file.bzl"). This client data is accessible to
 * (for instance) application-defined builtin methods.
 *
 * <p>You may create a Module using {@link #create}, {@link #withPredeclared}, or {@link
 * #withPredeclaredAndData}. The latter two give you the ability to add predeclared bindings (beyond
 * the universal ones) and client data. The particular {@link StarlarkSemantics} and client data may
 * filter what predeclared bindings are available via {@link GuardedValue}.
 */
public final class Module implements Resolver.Module {

  // The module's predeclared environment. Excludes UNIVERSE bindings.
  private ImmutableMap<String, Object> predeclared;

  // The module's global variables, in order of creation.
  private final LinkedHashMap<String, Integer> globalIndex = new LinkedHashMap<>();
  private Object[] globals = new Object[8];

  // An optional piece of application-specific metadata associated with the module/file.
  // Its toString appears to Starlark in str(function): "<function f from ...>".
  @Nullable private final Object clientData;

  // An optional doc string for the module. Set after construction when evaluating a .bzl file.
  @Nullable private String documentation;

  private Module(ImmutableMap<String, Object> predeclared, Object clientData) {
    this.predeclared = predeclared;
    this.clientData = clientData;
  }

  /**
   * Constructs a Module with the specified predeclared bindings (filtered by the semantics), in *
   * addition to the standard environment, {@link Starlark#UNIVERSE}. No client data is set.
   */
  public static Module withPredeclared(
      StarlarkSemantics semantics, Map<String, Object> predeclared) {
    return withPredeclaredAndData(semantics, predeclared, null);
  }

  /**
   * Constructs a Module as above, but with the specified client data -- an arbitrary
   * application-specific value to be associated with this Module. Client data may also affect the
   * filtering of predeclareds alongside the semantics.
   */
  public static Module withPredeclaredAndData(
      StarlarkSemantics semantics, Map<String, Object> predeclared, @Nullable Object clientData) {
    return new Module(filter(predeclared, semantics, clientData), clientData);
  }

  /**
   * Creates a module with no predeclared bindings other than the standard environment, {@link
   * Starlark#UNIVERSE}, and with no client data.
   */
  public static Module create() {
    return new Module(/*predeclared=*/ ImmutableMap.of(), null);
  }

  /**
   * Returns the module (file) of the innermost enclosing Starlark function on the call stack, or
   * null if none of the active calls are functions defined in Starlark.
   *
   * <p>The name of this function is intentionally horrible to make you feel bad for using it.
   */
  @Nullable
  public static Module ofInnermostEnclosingStarlarkFunction(StarlarkThread thread) {
    for (Debug.Frame fr : thread.getDebugCallStack().reverse()) {
      if (fr.getFunction() instanceof StarlarkFunction) {
        return ((StarlarkFunction) fr.getFunction()).getModule();
      }
    }
    return null;
  }

  /**
   * Returns a map in which each {@link GuardedValue} that is enabled has been replaced by the value
   * it guards. Disabled {@code GuardedValues} are left in place for error reporting upon access,
   * and should be treated as unavailable.
   *
   * <p>The iteration order is unchanged.
   */
  private static ImmutableMap<String, Object> filter(
      Map<String, Object> predeclared, StarlarkSemantics semantics, @Nullable Object clientData) {
    ImmutableMap.Builder<String, Object> filtered = ImmutableMap.builder();
    for (Map.Entry<String, Object> bind : predeclared.entrySet()) {
      Object v = bind.getValue();
      if (v instanceof GuardedValue) {
        GuardedValue gv = (GuardedValue) bind.getValue();
        if (gv.isObjectAccessibleUsingSemantics(semantics, clientData)) {
          v = gv.getObject();
        }
      }
      filtered.put(bind.getKey(), v);
    }
    return filtered.build();
  }

  /** Returns the client data associated with this module. */
  @Nullable
  public Object getClientData() {
    return clientData;
  }

  /** Sets the module's doc string. It may be retrieved using {@link #getDocumentation}. */
  public void setDocumentation(String documentation) {
    this.documentation = documentation;
  }

  /**
   * Returns the module's doc string, or null if absent.
   *
   * <p>Morally equivalent to calling {@code program.getResolvedFunction().getDocumentation()} when
   * the Module has a corresponding {@link net.starlark.java.syntax.Program}. We need to separately
   * save the doc string inside the Module because (1) a Module will usually outlive the Program;
   * and (2) there isn't always a 1-to-1 match between a Module and a Program (multiple programs may
   * be executed in the same module in REPL or in tests).
   */
  @Nullable
  public String getDocumentation() {
    return documentation;
  }

  /** Returns the value of a predeclared (not universal) binding in this module. */
  Object getPredeclared(String name) {
    return predeclared.get(name);
  }

  /**
   * Returns this module's additional predeclared bindings. (Excludes {@link Starlark#UNIVERSE}.)
   *
   * <p>The map reflects any filtering of {@link GuardedValue}: enabled ones are replaced by the
   * underlying values that they guard, while disabled ones are left in place for error reporting.
   */
  public ImmutableMap<String, Object> getPredeclaredBindings() {
    return predeclared;
  }

  /**
   * Returns an immutable mapping containing the global variables of this module.
   *
   * <p>The bindings are returned in a deterministic order (for a given sequence of initial values
   * and updates).
   */
  public ImmutableMap<String, Object> getGlobals() {
    int n = globalIndex.size();
    ImmutableMap.Builder<String, Object> m = ImmutableMap.builderWithExpectedSize(n);
    for (Map.Entry<String, Integer> e : globalIndex.entrySet()) {
      Object v = getGlobalByIndex(e.getValue());
      if (v != null) {
        m.put(e.getKey(), v);
      }
    }
    return m.build();
  }

  /** Implements the resolver's module interface. */
  @Override
  public Resolver.Scope resolve(String name) throws Undefined {
    // global?
    if (globalIndex.containsKey(name)) {
      return Resolver.Scope.GLOBAL;
    }

    // predeclared?
    Object v = predeclared.get(name);
    if (v != null) {
      if (v instanceof GuardedValue) {
        // Name is correctly spelled, but access is disabled by a flag or by client data.
        throw new Undefined(
            ((GuardedValue) v).getErrorFromAttemptingAccess(name), /*candidates=*/ null);
      }
      return Resolver.Scope.PREDECLARED;
    }

    // universal?
    if (Starlark.UNIVERSE.containsKey(name)) {
      return Resolver.Scope.UNIVERSAL;
    }

    // undefined
    Set<String> candidates = new HashSet<>();
    candidates.addAll(globalIndex.keySet());
    candidates.addAll(predeclared.keySet());
    candidates.addAll(Starlark.UNIVERSE.keySet());
    throw new Undefined(String.format("name '%s' is not defined", name), candidates);
  }

  /**
   * Returns the value of the specified global variable, or null if not bound. Does not look in the
   * predeclared environment.
   */
  @Nullable
  public Object getGlobal(String name) {
    Integer i = globalIndex.get(name);
    return i != null ? globals[i] : null;
  }

  /**
   * Sets the value of a global variable based on its index in this module ({@see
   * getIndexOfGlobal}).
   */
  void setGlobalByIndex(int i, Object v) {
    Preconditions.checkArgument(i < globalIndex.size());
    this.globals[i] = v;
  }

  /**
   * Returns the value of a global variable based on its index in this module ({@see
   * getIndexOfGlobal}.) Returns null if the variable has not been assigned a value.
   */
  @Nullable
  Object getGlobalByIndex(int i) {
    Preconditions.checkArgument(i < globalIndex.size());
    return this.globals[i];
  }

  /**
   * Returns the index within this Module of a global variable, given its name, creating a new slot
   * for it if needed. The numbering of globals used by these functions is not the same as the
   * numbering within any compiled Program. Thus each StarlarkFunction must contain a secondary
   * index mapping Program indices (from Binding.index) to Module indices.
   */
  int getIndexOfGlobal(String name) {
    int i = globalIndex.size();
    Integer prev = globalIndex.putIfAbsent(name, i);
    if (prev != null) {
      return prev;
    }
    if (i == globals.length) {
      globals = Arrays.copyOf(globals, globals.length << 1); // grow by doubling
    }
    return i;
  }

  /** Returns a list of indices of a list of globals; {@see getIndexOfGlobal}. */
  int[] getIndicesOfGlobals(List<String> globals) {
    int n = globals.size();
    int[] array = new int[n];
    for (int i = 0; i < n; i++) {
      array[i] = getIndexOfGlobal(globals.get(i));
    }
    return array;
  }

  /** Updates a global binding in the module environment. */
  public void setGlobal(String name, Object value) {
    Preconditions.checkNotNull(value, "Module.setGlobal(%s, null)", name);
    setGlobalByIndex(getIndexOfGlobal(name), value);
  }

  @Override
  public String toString() {
    return String.format("<module %s>", clientData == null ? "?" : clientData);
  }
}
