// 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 com.google.devtools.build.lib.syntax;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * 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").
 *
 * <p>Use {@link #create} to create a {@link Module} with no predeclared bindings other than the
 * universal ones. Use {@link #withPredeclared(StarlarkSemantics, Map)} to create a module with the
 * predeclared environment specified by the map, using the semantics to determine whether any
 * FlagGuardedValues in the map are enabled or disabled.
 */
public final class Module implements Resolver.Module {

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

  // The module's global bindings, in order of creation.
  private final LinkedHashMap<String, Object> globals = new LinkedHashMap<>();

  // Names of globals that are exported and can be loaded from other modules.
  // TODO(adonovan): eliminate this field when the resolver does its job properly.
  final HashSet<String> exportedGlobals = new HashSet<>();

  // An optional piece of metadata associated with the module/file.
  // May be set after construction (too obscure to burden the constructors).
  // Its toString appears to Starlark in str(function): "<function f from ...>".
  @Nullable private Object clientData;

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

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

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

  /**
   * 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 semantics-enabled FlagGuardedValue has been replaced by the value
   * it guards. Disabled FlagGuardedValues are left in place, and should be treated as unavailable.
   * The iteration order is unchanged.
   */
  private static ImmutableMap<String, Object> filter(
      Map<String, Object> predeclared, StarlarkSemantics semantics) {
    ImmutableMap.Builder<String, Object> filtered = ImmutableMap.builder();
    for (Map.Entry<String, Object> bind : predeclared.entrySet()) {
      Object v = bind.getValue();
      if (v instanceof FlagGuardedValue) {
        FlagGuardedValue fv = (FlagGuardedValue) bind.getValue();
        if (fv.isObjectAccessibleUsingSemantics(semantics)) {
          v = fv.getObject();
        }
      }
      filtered.put(bind.getKey(), v);
    }
    return filtered.build();
  }

  /**
   * Sets the client data (an arbitrary application-specific value) associated with the module. It
   * may be retrieved using {@link #getClientData}. Its {@code toString} form appears in the result
   * of {@code str(fn)} where {@code fn} is a StarlarkFunction: "<function f from ...>".
   */
  public void setClientData(@Nullable Object clientData) {
    this.clientData = clientData;
  }

  /**
   * Returns the client data associated with this module by a prior call to {@link #setClientData}.
   */
  @Nullable
  public Object getClientData() {
    return clientData;
  }

  /** Returns the value of a predeclared (or universal) binding in this module. */
  Object getPredeclared(String name) {
    Object v = predeclared.get(name);
    if (v != null) {
      return v;
    }
    return Starlark.UNIVERSE.get(name);
  }

  /**
   * Returns this module's additional predeclared bindings. (Excludes {@link Starlark#UNIVERSE}.)
   *
   * <p>The map reflects any semantics-based filtering of FlagGuardedValues done by {@link
   * #withPredeclared}: enabled FlagGuardedValues are replaced by their underlying value.
   */
  public ImmutableMap<String, Object> getPredeclaredBindings() {
    return predeclared;
  }

  /**
   * Returns a read-only view of this module's global bindings.
   *
   * <p>The bindings are returned in a deterministic order (for a given sequence of initial values
   * and updates).
   */
  public Map<String, Object> getGlobals() {
    return Collections.unmodifiableMap(globals);
  }

  /**
   * Returns a map of bindings that are exported (i.e. symbols declared using `=` and `def`, but not
   * `load`).
   */
  // TODO(adonovan): whether bindings are exported should be decided by the resolver;
  //  non-exported bindings should never be added to the module.  Delete this.
  public ImmutableMap<String, Object> getExportedGlobals() {
    ImmutableMap.Builder<String, Object> result = new ImmutableMap.Builder<>();
    for (Map.Entry<String, Object> entry : globals.entrySet()) {
      if (exportedGlobals.contains(entry.getKey())) {
        result.put(entry);
      }
    }
    return result.build();
  }

  /** Implements the resolver's module interface. */
  @Override
  public Set<String> getNames() {
    // TODO(adonovan): for now, the resolver treats all predeclared/universe
    //  and global names as one bucket (Scope.PREDECLARED). Fix that.
    // TODO(adonovan): opt: change the resolver to request names on
    //  demand to avoid all this set copying.
    HashSet<String> names = new HashSet<>();
    for (Map.Entry<String, Object> bind : getTransitiveBindings().entrySet()) {
      if (bind.getValue() instanceof FlagGuardedValue) {
        continue; // disabled
      }
      names.add(bind.getKey());
    }
    return names;
  }

  @Override
  public String getUndeclaredNameError(String name) {
    Object v = getPredeclared(name);
    return v instanceof FlagGuardedValue
        ? ((FlagGuardedValue) v).getErrorFromAttemptingAccess(name)
        : null;
  }

  /**
   * Returns a new map containing the predeclared (including universal) and global bindings of this
   * module.
   */
  // TODO(adonovan): eliminate; clients should explicitly choose getPredeclared or getGlobals.
  public Map<String, Object> getTransitiveBindings() {
    // Can't use ImmutableMap.Builder because it doesn't allow duplicates.
    LinkedHashMap<String, Object> env = new LinkedHashMap<>();
    env.putAll(Starlark.UNIVERSE);
    env.putAll(predeclared);
    env.putAll(globals);
    return env;
  }

  /**
   * Returns the value of the specified global variable, or null if not bound. Does not look in the
   * predeclared environment.
   */
  public Object getGlobal(String name) {
    return globals.get(name);
  }

  /**
   * Returns the value of the named variable in the module global environment (as if by {@link
   * #getGlobal}), or if not bound there, in the predeclared environment (as if by {@link
   * #getPredeclared}, or if not bound there, null.
   */
  public Object get(String name) {
    // TODO(adonovan): delete this whole function, and getTransitiveBindings.
    // With proper resolution, the interpreter will know whether
    // to look in the module or the predeclared/universal environment.
    Object v = getGlobal(name);
    if (v != null) {
      return v;
    }
    return getPredeclared(name);
  }

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

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