// Copyright 2015 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.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary;
import com.google.devtools.build.lib.skylarkinterface.SkylarkInterfaceUtils;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.Nullable;

/**
 * Global constants and support for static registration of builtin symbols.
 */
// TODO(bazel-team): Rename to SkylarkRuntime to avoid conflict with java.lang.Runtime.
public final class Runtime {

  private Runtime() {}

  @SkylarkSignature(name = "True", returnType = Boolean.class,
      doc = "Literal for the boolean true.")
  private static final Boolean TRUE = true;

  @SkylarkSignature(name = "False", returnType = Boolean.class,
      doc = "Literal for the boolean false.")
  private static final Boolean FALSE = false;

  /** There should be only one instance of this type to allow "== None" tests. */
  @SkylarkModule(
    name = "NoneType",
    documented = false,
    doc = "Unit type, containing the unique value None."
  )
  @Immutable
  public static final class NoneType implements SkylarkValue {
    private NoneType() {}

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

    @Override
    public boolean isImmutable() {
      return true;
    }

    @Override
    public void repr(SkylarkPrinter printer) {
      printer.append("None");
    }
  }

  /** Marker for unbound variables in cases where neither Java null nor Skylark None is suitable. */
  @Immutable
  public static final class UnboundMarker implements SkylarkValue {
    private UnboundMarker() {}

    @Override
    public String toString() {
      return "<unbound>";
    }

    @Override
    public boolean isImmutable() {
      return true;
    }

    @Override
    public void repr(SkylarkPrinter printer) {
      printer.append("<unbound>");
    }
  }

  @SkylarkSignature(name = "<unbound>", returnType = UnboundMarker.class, documented = false,
      doc = "Marker for unbound values in cases where neither Skylark None nor Java null can do.")
  public static final UnboundMarker UNBOUND = new UnboundMarker();

  @SkylarkSignature(name = "None", returnType = NoneType.class,
      doc = "Literal for the None value.")
  public static final NoneType NONE = new NoneType();

  @SkylarkSignature(name = "PACKAGE_NAME", returnType = String.class,
      doc = "<b>Deprecated. Use <a href=\"native.html#package_name\">package_name()</a> "
          + "instead.</b> The name of the package being evaluated. "
          + "For example, in the BUILD file <code>some/package/BUILD</code>, its value "
          + "will be <code>some/package</code>. "
          + "If the BUILD file calls a function defined in a .bzl file, PACKAGE_NAME will "
          + "match the caller BUILD file package. "
          + "In .bzl files, do not access PACKAGE_NAME at the file-level (outside of functions), "
          + "either directly or by calling a function at the file-level that accesses "
          + "PACKAGE_NAME (PACKAGE_NAME is only defined during BUILD file evaluation)."
          + "Here is an example of a .bzl file:<br>"
          + "<pre class=language-python>"
          + "# a = PACKAGE_NAME  # not allowed outside functions\n"
          + "def extension():\n"
          + "  return PACKAGE_NAME</pre>"
          + "In this case, <code>extension()</code> can be called from a BUILD file (even "
          + "indirectly), but not in a file-level expression in the .bzl file. "
          + "When implementing a rule, use <a href=\"ctx.html#label\">ctx.label</a> to know where "
          + "the rule comes from. ")
  public static final String PKG_NAME = "PACKAGE_NAME";

  @SkylarkSignature(
    name = "REPOSITORY_NAME",
    returnType = String.class,
    doc =
        "<b>Deprecated. Use <a href=\"native.html#repository_name\">repository_name()</a> "
            + "instead.</b> The name of the repository the rule or build extension is called from. "
            + "For example, in packages that are called into existence by the WORKSPACE stanza "
            + "<code>local_repository(name='local', path=...)</code> it will be set to "
            + "<code>@local</code>. In packages in the main repository, it will be set to "
            + "<code>@</code>. It can only be accessed in functions (transitively) called from "
            + "BUILD files, i.e. it follows the same restrictions as "
            + "<a href=\"#PACKAGE_NAME\">PACKAGE_NAME</a>"
  )
  public static final String REPOSITORY_NAME = "REPOSITORY_NAME";

  /** Adds bindings for False/True/None constants to the given map builder. */
  public static void addConstantsToBuilder(ImmutableMap.Builder<String, Object> builder) {
    // In Python 2.x, True and False are global values and can be redefined by the user.
    // In Python 3.x, they are keywords. We implement them as values. Currently they can't be
    // redefined because builtins can't be overridden. In the future we should permit shadowing of
    // most builtins but still prevent shadowing of these constants.
    builder
        .put("False", FALSE)
        .put("True", TRUE)
        .put("None", NONE);
  }


  /**
   * Returns the canonical class representing the namespace associated with the given class, i.e.,
   * the class under which builtins should be registered.
   */
  public static Class<?> getSkylarkNamespace(Class<?> clazz) {
    return String.class.isAssignableFrom(clazz)
        ? StringModule.class
        : EvalUtils.getSkylarkType(clazz);
  }

  /**
   * A registry of builtins, including both global builtins and builtins that are under some
   * namespace.
   *
   * <p>Concurrency model: This object is thread-safe. Read accesses are always allowed, while write
   * accesses are only allowed before this object has been frozen ({@link #freeze}). Prior to
   * freezing, all operations are synchronized, while after freezing they are lockless.
   */
  public static class BuiltinRegistry {

    /**
     * Whether the registry's construction has completed.
     *
     * <p>Mutating methods may only be called while this is still false. Accessor methods may be
     * called at any time.
     *
     * <p>We use {@code volatile} rather than {@link AtomicBoolean} because the bit flip only
     * happens once, and doesn't require correlated reads and writes.
     */
    private volatile boolean frozen = false;

    /**
     * All registered builtins, keyed and sorted by an identifying (but otherwise unimportant)
     * string.
     *
     * <p>The string is typically formed from the builtin's simple name and the Java class in which
     * it is defined. The Java class need not correspond to a namespace. (This map includes global
     * builtins that have no namespace.)
     */
    private final Map<String, Object> allBuiltins = new TreeMap<>();

    /** All non-global builtin functions, keyed by their namespace class and their name. */
    private final Map<Class<?>, Map<String, BaseFunction>> functions = new HashMap<>();

    /**
     * Marks the registry as initialized, if it wasn't already.
     *
     * <p>It is guaranteed that after this method returns, all accessor methods are safe without
     * synchronization; i.e. no mutation operation can touch the data structures.
     */
    public void freeze() {
      // Similar to double-checked locking, but no need to check again on the inside since we don't
      // care if two threads set the bit at once. The synchronized block is only to provide
      // exclusion with mutations.
      if (!this.frozen) {
        synchronized (this) {
          this.frozen = true;
        }
      }
    }

    /** Registers a builtin with the given simple name, that was defined in the given Java class. */
    public synchronized void registerBuiltin(Class<?> definingClass, String name, Object builtin) {
      String key = String.format("%s.%s", definingClass.getName(), name);
      Preconditions.checkArgument(
          !allBuiltins.containsKey(key),
          "Builtin '%s' registered multiple times",
          key);

      Preconditions.checkState(
          !frozen,
          "Attempted to register builtin '%s' after registry has already been frozen",
          key);

      allBuiltins.put(key, builtin);
    }

    /**
     * Registers a function underneath a namespace.
     *
     * <p>This is independent of {@link #registerBuiltin}.
     */
    public synchronized void registerFunction(Class<?> namespace, BaseFunction function) {
      Preconditions.checkNotNull(namespace);
      Preconditions.checkNotNull(function.getObjectType());
      Class<?> skylarkNamespace = getSkylarkNamespace(namespace);
      Preconditions.checkArgument(skylarkNamespace.equals(namespace));
      Class<?> objType = getSkylarkNamespace(function.getObjectType());
      Preconditions.checkArgument(objType.equals(skylarkNamespace));

      Preconditions.checkState(
          !frozen,
          "Attempted to register function '%s' in namespace '%s' after registry has already been "
              + "frozen",
          function,
          namespace);

      functions.computeIfAbsent(namespace, k -> new HashMap<>());
      functions.get(namespace).put(function.getName(), function);
    }

    /** Returns a list of all registered builtins, in a deterministic order. */
    public ImmutableList<Object> getBuiltins() {
      if (frozen) {
        return ImmutableList.copyOf(allBuiltins.values());
      } else {
        synchronized (this) {
          return ImmutableList.copyOf(allBuiltins.values());
        }
      }
    }

    @Nullable
    private Map<String, BaseFunction> getFunctionsInNamespace(Class<?> namespace) {
      return functions.get(getSkylarkNamespace(namespace));
    }

    /**
     * Given a namespace, returns the function with the given name.
     *
     * <p>If the namespace does not exist or has no function with that name, returns null.
     */
    public BaseFunction getFunction(Class<?> namespace, String name) {
      if (frozen) {
        Map<String, BaseFunction> namespaceFunctions = getFunctionsInNamespace(namespace);
        return namespaceFunctions != null ? namespaceFunctions.get(name) : null;
      } else {
        synchronized (this) {
          Map<String, BaseFunction> namespaceFunctions = getFunctionsInNamespace(namespace);
          return namespaceFunctions != null ? namespaceFunctions.get(name) : null;
        }
      }
    }

    /**
     * Given a namespace, returns all function names.
     *
     * <p>If the namespace does not exist, returns an empty set.
     */
    public ImmutableSet<String> getFunctionNames(Class<?> namespace) {
      if (frozen) {
        Map<String, BaseFunction> namespaceFunctions = getFunctionsInNamespace(namespace);
        if (namespaceFunctions == null) {
          return ImmutableSet.of();
        }
        return ImmutableSet.copyOf(namespaceFunctions.keySet());
      } else {
        synchronized (this) {
          Map<String, BaseFunction> namespaceFunctions = getFunctionsInNamespace(namespace);
          if (namespaceFunctions == null) {
            return ImmutableSet.of();
          }
          return ImmutableSet.copyOf(namespaceFunctions.keySet());
        }
      }
    }
  }

  /**
   * All Skylark builtins.
   *
   * <p>Note that just because a symbol is registered here does not necessarily mean that it is
   * accessible in a particular {@link Environment}. This registry should include any builtin that
   * is available in any environment.
   *
   * <p>Thread safety: This object is unsynchronized. The register functions are typically called
   * from within static initializer blocks, which should be fine.
   */
  private static final BuiltinRegistry builtins = new BuiltinRegistry();

  /** Retrieve the static instance containing information on all known Skylark builtins. */
  public static BuiltinRegistry getBuiltinRegistry() {
    return builtins;
  }

  /**
   * Convenience overload of {@link #setupModuleGlobals(ImmutableMap.Builder, Class)} to add
   * bindings directly to an {@link Environment}.
   *
   * @param env the Environment into which to register fields.
   * @param moduleClass the Class object containing globals.
   */
  public static void setupModuleGlobals(Environment env, Class<?> moduleClass) {
    ImmutableMap.Builder<String, Object> envBuilder = ImmutableMap.builder();

    setupModuleGlobals(envBuilder, moduleClass);
    for (Map.Entry<String, Object> envEntry : envBuilder.build().entrySet()) {
      env.setup(envEntry.getKey(), envEntry.getValue());
    }
  }

  /**
   * Adds global (top-level) symbols, provided by the given class object, to the given bindings
   * builder.
   *
   * <p>Global symbols may be provided by the given class in the following ways:
   * <ul>
   *   <li>If the class is annotated with {@link SkylarkModule}, an instance of that object is
   *       a global object with the module's name.</li>
   *   <li>If the class has fields annotated with {@link SkylarkSignature}, each of these
   *       fields is a global object with the signature's name.</li>
   *   <li>If the class is annotated with {@link SkylarkGlobalLibrary}, then all of its methods
   *       which are annotated with
   *       {@link com.google.devtools.build.lib.skylarkinterface.SkylarkCallable} are global
   *       callables.</li>
   * </ul>
   *
   * <p>On collisions, this method throws an {@link AssertionError}. Collisions may occur if
   * multiple global libraries have functions of the same name, two modules of the same name
   * are given, or if two subclasses of the same module are given.
   *
   * @param builder the builder for the "bindings" map, which maps from symbol names to objects,
   *     and which will be built into a global frame
   * @param moduleClass the Class object containing globals
   */
  public static void setupModuleGlobals(ImmutableMap.Builder<String, Object> builder,
      Class<?> moduleClass) {
    try {
      SkylarkModule skylarkModule = SkylarkInterfaceUtils.getSkylarkModule(moduleClass);
      if (skylarkModule != null) {
        builder.put(
            skylarkModule.name(),
            moduleClass.getConstructor().newInstance());
      }
      for (Field field : moduleClass.getDeclaredFields()) {
        if (field.isAnnotationPresent(SkylarkSignature.class)) {
          // Fields in Skylark modules are sometimes private.
          // Nevertheless they have to be annotated with SkylarkSignature.
          field.setAccessible(true);
          SkylarkSignature annotation = field.getAnnotation(SkylarkSignature.class);
          Object value = field.get(null);
          // Ignore function factories and non-global functions
          if (!(value instanceof BuiltinFunction.Factory
              || (value instanceof BaseFunction
                  && !annotation.objectType().equals(Object.class)))) {
            builder.put(annotation.name(), value);
          }
        }
      }
      if (SkylarkInterfaceUtils.hasSkylarkGlobalLibrary(moduleClass)) {
        Object moduleInstance = moduleClass.getConstructor().newInstance();
        for (String methodName : FuncallExpression.getMethodNames(moduleClass)) {
          builder.put(methodName, FuncallExpression.getBuiltinCallable(moduleInstance, methodName));
        }
      }
    } catch (ReflectiveOperationException e) {
      throw new AssertionError(e);
    }
  }
}
