// Copyright 2014 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 static java.util.stream.Collectors.joining;

import com.google.common.base.Ascii;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.syntax.EvalUtils.ComparisonException;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeSet;
import javax.annotation.Nullable;

/** A helper class containing built in functions for the Skylark language. */
public class MethodLibrary {

  private MethodLibrary() {}

  @SkylarkSignature(
      name = "min",
      returnType = Object.class,
      doc =
          "Returns the smallest one of all given arguments. "
              + "If only one argument is provided, it must be a non-empty iterable. "
              + "It is an error if elements are not comparable (for example int with string). "
              + "<pre class=\"language-python\">min(2, 5, 4) == 2\n"
              + "min([5, 6, 3]) == 3</pre>",
      extraPositionals =
          @Param(name = "args", type = SkylarkList.class, doc = "The elements to be checked."),
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction min =
      new BuiltinFunction("min") {
        @SuppressWarnings("unused") // Accessed via Reflection.
        public Object invoke(SkylarkList<?> args, Location loc, Environment env)
            throws EvalException {
          try {
            return findExtreme(args, EvalUtils.SKYLARK_COMPARATOR.reverse(), loc, env);
          } catch (ComparisonException e) {
            throw new EvalException(loc, e);
          }
        }
      };

  @SkylarkSignature(
      name = "max",
      returnType = Object.class,
      doc =
          "Returns the largest one of all given arguments. "
              + "If only one argument is provided, it must be a non-empty iterable."
              + "It is an error if elements are not comparable (for example int with string). "
              + "<pre class=\"language-python\">max(2, 5, 4) == 5\n"
              + "max([5, 6, 3]) == 6</pre>",
      extraPositionals =
          @Param(name = "args", type = SkylarkList.class, doc = "The elements to be checked."),
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction max =
      new BuiltinFunction("max") {
        @SuppressWarnings("unused") // Accessed via Reflection.
        public Object invoke(SkylarkList<?> args, Location loc, Environment env)
            throws EvalException {
          try {
            return findExtreme(args, EvalUtils.SKYLARK_COMPARATOR, loc, env);
          } catch (ComparisonException e) {
            throw new EvalException(loc, e);
          }
        }
      };

  /** Returns the maximum element from this list, as determined by maxOrdering. */
  private static Object findExtreme(
      SkylarkList<?> args, Ordering<Object> maxOrdering, Location loc, Environment env)
      throws EvalException {
    // Args can either be a list of items to compare, or a singleton list whose element is an
    // iterable of items to compare. In either case, there must be at least one item to compare.
    try {
      Iterable<?> items = (args.size() == 1) ? EvalUtils.toIterable(args.get(0), loc, env) : args;
      return maxOrdering.max(items);
    } catch (NoSuchElementException ex) {
      throw new EvalException(loc, "expected at least one item", ex);
    }
  }

  @SkylarkSignature(
      name = "all",
      returnType = Boolean.class,
      doc =
          "Returns true if all elements evaluate to True or if the collection is empty. "
              + "Elements are converted to boolean using the <a href=\"#bool\">bool</a> function."
              + "<pre class=\"language-python\">all([\"hello\", 3, True]) == True\n"
              + "all([-1, 0, 1]) == False</pre>",
      parameters = {
        @Param(
            name = "elements",
            type = Object.class,
            doc = "A string or a collection of elements.")
      },
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction all =
      new BuiltinFunction("all") {
        @SuppressWarnings("unused") // Accessed via Reflection.
        public Boolean invoke(Object collection, Location loc, Environment env)
            throws EvalException {
          return !hasElementWithBooleanValue(collection, false, loc, env);
        }
      };

  @SkylarkSignature(
      name = "any",
      returnType = Boolean.class,
      doc =
          "Returns true if at least one element evaluates to True. "
              + "Elements are converted to boolean using the <a href=\"#bool\">bool</a> function."
              + "<pre class=\"language-python\">any([-1, 0, 1]) == True\n"
              + "any([False, 0, \"\"]) == False</pre>",
      parameters = {
        @Param(
            name = "elements",
            type = Object.class,
            doc = "A string or a collection of elements.")
      },
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction any =
      new BuiltinFunction("any") {
        @SuppressWarnings("unused") // Accessed via Reflection.
        public Boolean invoke(Object collection, Location loc, Environment env)
            throws EvalException {
          return hasElementWithBooleanValue(collection, true, loc, env);
        }
      };

  private static boolean hasElementWithBooleanValue(
      Object collection, boolean value, Location loc, Environment env) throws EvalException {
    Iterable<?> iterable = EvalUtils.toIterable(collection, loc, env);
    for (Object obj : iterable) {
      if (EvalUtils.toBoolean(obj) == value) {
        return true;
      }
    }
    return false;
  }

  // supported list methods
  @SkylarkSignature(
      name = "sorted",
      returnType = MutableList.class,
      doc =
          "Sort a collection. Elements should all belong to the same orderable type, they are "
              + "sorted by their value (in ascending order). "
              + "It is an error if elements are not comparable (for example int with string)."
              + "<pre class=\"language-python\">sorted([3, 5, 4]) == [3, 4, 5]</pre>",
      parameters = {@Param(name = "self", type = Object.class, doc = "This collection.")},
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction sorted =
      new BuiltinFunction("sorted") {
        public MutableList<?> invoke(Object self, Location loc, Environment env)
            throws EvalException {
          try {
            return MutableList.copyOf(
                env,
                EvalUtils.SKYLARK_COMPARATOR.sortedCopy(EvalUtils.toCollection(self, loc, env)));
          } catch (EvalUtils.ComparisonException e) {
            throw new EvalException(loc, e);
          }
        }
      };

  @SkylarkSignature(
      name = "reversed",
      returnType = MutableList.class,
      doc =
          "Returns a list that contains the elements of the original sequence in reversed order."
              + "<pre class=\"language-python\">reversed([3, 5, 4]) == [4, 5, 3]</pre>",
      parameters = {
        @Param(
            name = "sequence",
            type = Object.class,
            doc = "The sequence to be reversed (string, list or tuple).")
      },
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction reversed =
      new BuiltinFunction("reversed") {
        @SuppressWarnings("unused") // Accessed via Reflection.
        public MutableList<?> invoke(Object sequence, Location loc, Environment env)
            throws EvalException {
          // We only allow lists and strings.
          if (sequence instanceof SkylarkDict) {
            throw new EvalException(
                loc, "Argument to reversed() must be a sequence, not a dictionary.");
          } else if (sequence instanceof NestedSet || sequence instanceof SkylarkNestedSet) {
            throw new EvalException(
                loc, "Argument to reversed() must be a sequence, not a depset.");
          }
          ArrayDeque<Object> tmpList = new ArrayDeque<>();
          for (Object element : EvalUtils.toIterable(sequence, loc, env)) {
            tmpList.addFirst(element);
          }
          return MutableList.copyOf(env, tmpList);
        }
      };

  @SkylarkSignature(
      name = "tuple",
      returnType = Tuple.class,
      doc =
          "Converts a collection (e.g. list, tuple or dictionary) to a tuple."
              + "<pre class=\"language-python\">tuple([1, 2]) == (1, 2)\n"
              + "tuple((2, 3, 2)) == (2, 3, 2)\n"
              + "tuple({5: \"a\", 2: \"b\", 4: \"c\"}) == (5, 2, 4)</pre>",
      parameters = {@Param(name = "x", doc = "The object to convert.")},
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction tuple =
      new BuiltinFunction("tuple") {
        public Tuple<?> invoke(Object x, Location loc, Environment env) throws EvalException {
          return Tuple.copyOf(EvalUtils.toCollection(x, loc, env));
        }
      };

  @SkylarkSignature(
      name = "list",
      returnType = MutableList.class,
      doc =
          "Converts a collection (e.g. list, tuple or dictionary) to a list."
              + "<pre class=\"language-python\">list([1, 2]) == [1, 2]\n"
              + "list((2, 3, 2)) == [2, 3, 2]\n"
              + "list({5: \"a\", 2: \"b\", 4: \"c\"}) == [5, 2, 4]</pre>",
      parameters = {@Param(name = "x", doc = "The object to convert.")},
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction list =
      new BuiltinFunction("list") {
        public MutableList<?> invoke(Object x, Location loc, Environment env) throws EvalException {
          return MutableList.copyOf(env, EvalUtils.toCollection(x, loc, env));
        }
      };

  @SkylarkSignature(
      name = "len",
      returnType = Integer.class,
      doc = "Returns the length of a string, list, tuple, depset, or dictionary.",
      parameters = {@Param(name = "x", doc = "The object to check length of.")},
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction len =
      new BuiltinFunction("len") {
        public Integer invoke(Object x, Location loc, Environment env) throws EvalException {
          if (x instanceof String) {
            return ((String) x).length();
          } else if (x instanceof Map) {
            return ((Map<?, ?>) x).size();
          } else if (x instanceof SkylarkList) {
            return ((SkylarkList<?>) x).size();
          } else if (x instanceof SkylarkNestedSet) {
            if (env.getSemantics().incompatibleDepsetIsNotIterable()) {
              throw new EvalException(
                  loc,
                  EvalUtils.getDataTypeName(x)
                      + " is not iterable. You may use `len(<depset>.to_list())` instead. Use "
                      + "--incompatible_depset_is_not_iterable=false to temporarily disable this "
                      + "check.");
            }
            return ((SkylarkNestedSet) x).toCollection().size();
          } else if (x instanceof Iterable) {
            // Iterables.size() checks if x is a Collection so it's efficient in that sense.
            return Iterables.size((Iterable<?>) x);
          } else {
            throw new EvalException(loc, EvalUtils.getDataTypeName(x) + " is not iterable");
          }
        }
      };

  @SkylarkSignature(
      name = "str",
      returnType = String.class,
      doc =
          "Converts any object to string. This is useful for debugging."
              + "<pre class=\"language-python\">str(\"ab\") == \"ab\"\n"
              + "str(8) == \"8\"</pre>",
      parameters = {@Param(name = "x", doc = "The object to convert.")})
  private static final BuiltinFunction str =
      new BuiltinFunction("str") {
        public String invoke(Object x) {
          return Printer.str(x);
        }
      };

  @SkylarkSignature(
      name = "repr",
      returnType = String.class,
      doc =
          "Converts any object to a string representation. This is useful for debugging.<br>"
              + "<pre class=\"language-python\">repr(\"ab\") == '\"ab\"'</pre>",
      parameters = {@Param(name = "x", doc = "The object to convert.")})
  private static final BuiltinFunction repr =
      new BuiltinFunction("repr") {
        public String invoke(Object x) {
          return Printer.repr(x);
        }
      };

  @SkylarkSignature(
      name = "bool",
      returnType = Boolean.class,
      doc =
          "Constructor for the bool type. "
              + "It returns <code>False</code> if the object is <code>None</code>, <code>False"
              + "</code>, an empty string (<code>\"\"</code>), the number <code>0</code>, or an "
              + "empty collection (e.g. <code>()</code>, <code>[]</code>). "
              + "Otherwise, it returns <code>True</code>.",
      parameters = {@Param(name = "x", doc = "The variable to convert.")})
  private static final BuiltinFunction bool =
      new BuiltinFunction("bool") {
        public Boolean invoke(Object x) throws EvalException {
          return EvalUtils.toBoolean(x);
        }
      };

  @SkylarkSignature(
      name = "int",
      returnType = Integer.class,
      doc =
          "Returns x as an int value."
              + "<ul>"
              + "<li>If <code>x</code> is already an int, it is returned as-is."
              + "<li>If <code>x</code> is a boolean, a true value returns 1 and a false value "
              + "    returns 0."
              + "<li>If <code>x</code> is a string, it must have the format "
              + "    <code>&lt;sign&gt;&lt;prefix&gt;&lt;digits&gt;</code>. "
              + "    <code>&lt;sign&gt;</code> is either <code>\"+\"</code>, <code>\"-\"</code>, "
              + "    or empty (interpreted as positive). <code>&lt;digits&gt;</code> are a "
              + "    sequence of digits from 0 up to <code>base</code> - 1, where the letters a-z "
              + "    (or equivalently, A-Z) are used as digits for 10-35. In the case where "
              + "    <code>base</code> is 2/8/16, <code>&lt;prefix&gt;</code> is optional and may "
              + "    be 0b/0o/0x (or equivalently, 0B/0O/0X) respectively; if the "
              + "    <code>base</code> is any other value besides these bases or the special value "
              + "    0, the prefix must be empty. In the case where <code>base</code> is 0, the "
              + "    string is interpreted as an integer literal, in the sense that one of the "
              + "    bases 2/8/10/16 is chosen depending on which prefix if any is used. If "
              + "    <code>base</code> is 0, no prefix is used, and there is more than one digit, "
              + "    the leading digit cannot be 0; this is to avoid confusion between octal and "
              + "    decimal. The magnitude of the number represented by the string must be within "
              + "    the allowed range for the int type."
              + "</ul>"
              + "This function fails if <code>x</code> is any other type, or if the value is a "
              + "string not satisfying the above format. Unlike Python's <code>int()</code> "
              + "function, this function does not allow zero arguments, and does not allow "
              + "extraneous whitespace for string arguments."
              + "<p>Examples:"
              + "<pre class=\"language-python\">"
              + "int(\"123\") == 123\n"
              + "int(\"-123\") == -123\n"
              + "int(\"+123\") == 123\n"
              + "int(\"FF\", 16) == 255\n"
              + "int(\"0xFF\", 16) == 255\n"
              + "int(\"10\", 0) == 10\n"
              + "int(\"-0x10\", 0) == -16"
              + "</pre>",
      parameters = {
        @Param(name = "x", type = Object.class, doc = "The string to convert."),
        @Param(
            name = "base",
            type = Object.class,
            defaultValue = "unbound",
            doc =
                "The base used to interpret a string value; defaults to 10. Must be between 2 "
                    + "and 36 (inclusive), or 0 to detect the base as if <code>x</code> were an "
                    + "integer literal. This parameter must not be supplied if the value is not a "
                    + "string.")
      },
      useLocation = true)
  private static final BuiltinFunction int_ =
      new BuiltinFunction("int") {
        private final ImmutableMap<String, Integer> intPrefixes =
            ImmutableMap.of("0b", 2, "0o", 8, "0x", 16);

        @SuppressWarnings("unused")
        public Integer invoke(Object x, Object base, Location loc) throws EvalException {
          if (x instanceof String) {
            if (base == Runtime.UNBOUND) {
              base = 10;
            } else if (!(base instanceof Integer)) {
              throw new EvalException(
                  loc, "base must be an integer (got '" + EvalUtils.getDataTypeName(base) + "')");
            }
            return fromString((String) x, loc, (Integer) base);
          } else {
            if (base != Runtime.UNBOUND) {
              throw new EvalException(loc, "int() can't convert non-string with explicit base");
            }
            if (x instanceof Boolean) {
              return ((Boolean) x).booleanValue() ? 1 : 0;
            } else if (x instanceof Integer) {
              return (Integer) x;
            }
            throw new EvalException(
                loc, Printer.format("%r is not of type string or int or bool", x));
          }
        }

        private int fromString(String string, Location loc, int base) throws EvalException {
          String stringForErrors = string;

          boolean isNegative = false;
          if (string.isEmpty()) {
            throw new EvalException(
                loc, Printer.format("string argument to int() cannot be empty"));
          }
          char c = string.charAt(0);
          if (c == '+') {
            string = string.substring(1);
          } else if (c == '-') {
            string = string.substring(1);
            isNegative = true;
          }

          String prefix = getIntegerPrefix(string);
          String digits;
          if (prefix == null) {
            // Nothing to strip. Infer base 10 if autodetection was requested (base == 0).
            digits = string;
            if (base == 0) {
              if (string.length() > 1 && string.startsWith("0")) {
                // We don't infer the base when input starts with '0' (due
                // to confusion between octal and decimal).
                throw new EvalException(
                    loc,
                    Printer.format(
                        "cannot infer base for int() when value begins with a 0: %r",
                        stringForErrors));
              }
              base = 10;
            }
          } else {
            // Strip prefix. Infer base from prefix if unknown (base == 0), or else verify its
            // consistency.
            digits = string.substring(prefix.length());
            int expectedBase = intPrefixes.get(prefix);
            if (base == 0) {
              base = expectedBase;
            } else if (base != expectedBase) {
              throw new EvalException(
                  loc,
                  Printer.format(
                      "invalid literal for int() with base %d: %r", base, stringForErrors));
            }
          }

          if (base < 2 || base > 36) {
            throw new EvalException(loc, "int() base must be >= 2 and <= 36");
          }
          try {
            // Negate by prepending a negative symbol, rather than by using arithmetic on the
            // result, to handle the edge case of -2^31 correctly.
            String parseable = isNegative ? "-" + digits : digits;
            return Integer.parseInt(parseable, base);
          } catch (NumberFormatException | ArithmeticException e) {
            throw new EvalException(
                loc,
                Printer.format("invalid literal for int() with base %d: %r", base, stringForErrors),
                e);
          }
        }

        @Nullable
        private String getIntegerPrefix(String value) {
          value = Ascii.toLowerCase(value);
          for (String prefix : intPrefixes.keySet()) {
            if (value.startsWith(prefix)) {
              return prefix;
            }
          }
          return null;
        }
      };

  @SkylarkSignature(
      name = "dict",
      returnType = SkylarkDict.class,
      doc =
          "Creates a <a href=\"dict.html\">dictionary</a> from an optional positional "
              + "argument and an optional set of keyword arguments. In the case where the same key "
              + "is given multiple times, the last value will be used. Entries supplied via "
              + "keyword arguments are considered to come after entries supplied via the "
              + "positional argument.",
      parameters = {
        @Param(
            name = "args",
            type = Object.class,
            defaultValue = "[]",
            doc =
                "Either a dictionary or a list of entries. Entries must be tuples or lists with "
                    + "exactly two elements: key, value."),
      },
      extraKeywords = @Param(name = "kwargs", doc = "Dictionary of additional entries."),
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction dict =
      new BuiltinFunction("dict") {
        public SkylarkDict<?, ?> invoke(
            Object args, SkylarkDict<String, Object> kwargs, Location loc, Environment env)
            throws EvalException {
          SkylarkDict<?, ?> argsDict =
              (args instanceof SkylarkDict)
                  ? (SkylarkDict<?, ?>) args
                  : SkylarkDict.getDictFromArgs(args, loc, env);
          return SkylarkDict.plus(argsDict, kwargs, env);
        }
      };

  @SkylarkSignature(
      name = "enumerate",
      returnType = MutableList.class,
      doc =
          "Returns a list of pairs (two-element tuples), with the index (int) and the item from"
              + " the input list.\n<pre class=\"language-python\">"
              + "enumerate([24, 21, 84]) == [(0, 24), (1, 21), (2, 84)]</pre>\n",
      parameters = {@Param(name = "list", type = SkylarkList.class, doc = "input list.")},
      useEnvironment = true)
  private static final BuiltinFunction enumerate =
      new BuiltinFunction("enumerate") {
        public MutableList<?> invoke(SkylarkList<?> input, Environment env) throws EvalException {
          int count = 0;
          ArrayList<SkylarkList<?>> result = new ArrayList<>(input.size());
          for (Object obj : input) {
            result.add(Tuple.of(count, obj));
            count++;
          }
          return MutableList.wrapUnsafe(env, result);
        }
      };

  @SkylarkSignature(
      name = "hash",
      returnType = Integer.class,
      doc =
          "Return a hash value for a string. This is computed deterministically using the same "
              + "algorithm as Java's <code>String.hashCode()</code>, namely: "
              + "<pre class=\"language-python\">s[0] * (31^(n-1)) + s[1] * (31^(n-2)) + ... + "
              + "s[n-1]</pre> Hashing of values besides strings is not currently supported.",
      // Deterministic hashing is important for the consistency of builds, hence why we
      // promise a specific algorithm. This is in contrast to Java (Object.hashCode()) and
      // Python, which promise stable hashing only within a given execution of the program.
      parameters = {@Param(name = "value", type = String.class, doc = "String value to hash.")})
  private static final BuiltinFunction hash =
      new BuiltinFunction("hash") {
        public Integer invoke(String value) throws EvalException {
          return value.hashCode();
        }
      };

  @SkylarkSignature(
      name = "range",
      returnType = SkylarkList.class,
      doc =
          "Creates a list where items go from <code>start</code> to <code>stop</code>, using a "
              + "<code>step</code> increment. If a single argument is provided, items will "
              + "range from 0 to that element."
              + "<pre class=\"language-python\">range(4) == [0, 1, 2, 3]\n"
              + "range(3, 9, 2) == [3, 5, 7]\n"
              + "range(3, 0, -1) == [3, 2, 1]</pre>",
      parameters = {
        @Param(
            name = "start_or_stop",
            type = Integer.class,
            doc =
                "Value of the start element if stop is provided, "
                    + "otherwise value of stop and the actual start is 0"),
        @Param(
            name = "stop_or_none",
            type = Integer.class,
            noneable = true,
            defaultValue = "None",
            doc =
                "optional index of the first item <i>not</i> to be included in the resulting "
                    + "list; generation of the list stops before <code>stop</code> is reached."),
        @Param(
            name = "step",
            type = Integer.class,
            defaultValue = "1",
            doc = "The increment (default is 1). It may be negative.")
      },
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction range =
      new BuiltinFunction("range") {
        public SkylarkList<Integer> invoke(
            Integer startOrStop, Object stopOrNone, Integer step, Location loc, Environment env)
            throws EvalException {
          int start;
          int stop;
          if (stopOrNone == Runtime.NONE) {
            start = 0;
            stop = startOrStop;
          } else {
            start = startOrStop;
            stop = Type.INTEGER.convert(stopOrNone, "'stop' operand of 'range'");
          }
          if (step == 0) {
            throw new EvalException(loc, "step cannot be 0");
          }
          return RangeList.of(start, stop, step);
        }
      };

  /** Returns true if the object has a field of the given name, otherwise false. */
  @SkylarkSignature(
      name = "hasattr",
      returnType = Boolean.class,
      doc =
          "Returns True if the object <code>x</code> has an attribute or method of the given "
              + "<code>name</code>, otherwise False. Example:<br>"
              + "<pre class=\"language-python\">hasattr(ctx.attr, \"myattr\")</pre>",
      parameters = {
        @Param(name = "x", doc = "The object to check."),
        @Param(name = "name", type = String.class, doc = "The name of the attribute.")
      },
      useEnvironment = true)
  private static final BuiltinFunction hasattr =
      new BuiltinFunction("hasattr") {
        @SuppressWarnings("unused")
        public Boolean invoke(Object obj, String name, Environment env) throws EvalException {
          if (obj instanceof ClassObject && ((ClassObject) obj).getValue(name) != null) {
            return true;
          }
          // shouldn't this filter things with struct_field = false?
          return DotExpression.hasMethod(env.getSemantics(), obj, name);
        }
      };

  @SkylarkSignature(
      name = "getattr",
      doc =
          "Returns the struct's field of the given name if it exists. If not, it either returns "
              + "<code>default</code> (if specified) or raises an error. Built-in methods cannot "
              + "currently be retrieved in this way; doing so will result in an error if a "
              + "<code>default</code> is not given. <code>getattr(x, \"foobar\")</code> is "
              + "equivalent to <code>x.foobar</code>."
              + "<pre class=\"language-python\">getattr(ctx.attr, \"myattr\")\n"
              + "getattr(ctx.attr, \"myattr\", \"mydefault\")</pre>",
      parameters = {
        @Param(name = "x", doc = "The struct whose attribute is accessed."),
        @Param(name = "name", doc = "The name of the struct attribute."),
        @Param(
            name = "default",
            defaultValue = "unbound",
            doc =
                "The default value to return in case the struct "
                    + "doesn't have an attribute of the given name.")
      },
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction getattr =
      new BuiltinFunction("getattr") {
        @SuppressWarnings("unused")
        public Object invoke(
            Object obj, String name, Object defaultValue, Location loc, Environment env)
            throws EvalException, InterruptedException {
          Object result = DotExpression.eval(obj, name, loc, env);
          if (result == null) {
            if (defaultValue != Runtime.UNBOUND) {
              return defaultValue;
            }
            throw DotExpression.getMissingFieldException(
                obj, name, loc, env.getSemantics(), "attribute");
          }
          return result;
        }
      };

  @SkylarkSignature(
      name = "dir",
      returnType = MutableList.class,
      doc =
          "Returns a list of strings: the names of the attributes and "
              + "methods of the parameter object.",
      parameters = {@Param(name = "x", doc = "The object to check.")},
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction dir =
      new BuiltinFunction("dir") {
        public MutableList<?> invoke(Object object, Location loc, Environment env)
            throws EvalException {
          // Order the fields alphabetically.
          Set<String> fields = new TreeSet<>();
          if (object instanceof ClassObject) {
            fields.addAll(((ClassObject) object).getFieldNames());
          }
          fields.addAll(Runtime.getBuiltinRegistry().getFunctionNames(object.getClass()));
          fields.addAll(FuncallExpression.getMethodNames(env.getSemantics(), object.getClass()));
          return MutableList.copyOf(env, fields);
        }
      };

  @SkylarkSignature(
      name = "fail",
      doc =
          "Raises an error that cannot be intercepted. It can be used anywhere, "
              + "both in the loading phase and in the analysis phase.",
      returnType = Runtime.NoneType.class,
      parameters = {
        @Param(
            name = "msg",
            type = Object.class,
            doc = "Error to display for the user. The object is converted to a string."),
        @Param(
            name = "attr",
            type = String.class,
            noneable = true,
            defaultValue = "None",
            doc =
                "The name of the attribute that caused the error. This is used only for "
                    + "error reporting.")
      },
      useLocation = true)
  private static final BuiltinFunction fail =
      new BuiltinFunction("fail") {
        public Runtime.NoneType invoke(Object msg, Object attr, Location loc) throws EvalException {
          String str = Printer.str(msg);
          if (attr != Runtime.NONE) {
            str = String.format("attribute %s: %s", attr, str);
          }
          throw new EvalException(loc, str);
        }
      };

  @SkylarkSignature(
      name = "print",
      returnType = Runtime.NoneType.class,
      doc =
          "Prints <code>args</code> as debug output. It will be prefixed with the string <code>"
              + "\"DEBUG\"</code> and the location (file and line number) of this call. The "
              + "exact way in which the arguments are converted to strings is unspecified and may "
              + "change at any time. In particular, it may be different from (and more detailed "
              + "than) the formatting done by <a href='#str'><code>str()</code></a> and <a "
              + "href='#repr'><code>repr()</code></a>."
              + "<p>Using <code>print</code> in production code is discouraged due to the spam it "
              + "creates for users. For deprecations, prefer a hard error using <a href=\"#fail\">"
              + "<code>fail()</code></a> whenever possible.",
      parameters = {
        @Param(
            name = "sep",
            type = String.class,
            defaultValue = "\" \"",
            named = true,
            positional = false,
            doc = "The separator string between the objects, default is space (\" \").")
      },
      // NB: as compared to Python3, we're missing optional named-only arguments 'end' and 'file'
      extraPositionals = @Param(name = "args", doc = "The objects to print."),
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction print =
      new BuiltinFunction("print") {
        public Runtime.NoneType invoke(
            String sep, SkylarkList<?> starargs, Location loc, Environment env)
            throws EvalException {
          String msg = starargs.stream().map(Printer::debugPrint).collect(joining(sep));
          // As part of the integration test "skylark_flag_test.sh", if the
          // "--internal_skylark_flag_test_canary" flag is enabled, append an extra marker string to
          // the output.
          if (env.getSemantics().internalSkylarkFlagTestCanary()) {
            msg += "<== skylark flag test ==>";
          }
          env.handleEvent(Event.debug(loc, msg));
          return Runtime.NONE;
        }
      };

  @SkylarkSignature(
      name = "type",
      returnType = String.class,
      doc =
          "Returns the type name of its argument. This is useful for debugging and "
              + "type-checking. Examples:"
              + "<pre class=\"language-python\">"
              + "type(2) == \"int\"\n"
              + "type([1]) == \"list\"\n"
              + "type(struct(a = 2)) == \"struct\""
              + "</pre>"
              + "This function might change in the future. To write Python-compatible code and "
              + "be future-proof, use it only to compare return values: "
              + "<pre class=\"language-python\">"
              + "if type(x) == type([]):  # if x is a list"
              + "</pre>",
      parameters = {@Param(name = "x", doc = "The object to check type of.")})
  private static final BuiltinFunction type =
      new BuiltinFunction("type") {
        public String invoke(Object object) {
          // There is no 'type' type in Skylark, so we return a string with the type name.
          return EvalUtils.getDataTypeName(object, false);
        }
      };

  @SkylarkSignature(
      name = "depset",
      returnType = SkylarkNestedSet.class,
      doc =
          "Creates a <a href=\"depset.html\">depset</a>. The <code>direct</code> parameter is a "
              + "list of direct elements of the depset, and <code>transitive</code> parameter is "
              + "a list of depsets whose elements become indirect elements of the created depset. "
              + "The order in which elements are returned when the depset is converted to a list "
              + "is specified by the <code>order</code> parameter. "
              + "See the <a href=\"../depsets.md\">Depsets overview</a> for more information. "
              + "<p> All elements (direct and indirect) of a depset must be of the same type. "
              + "<p> The order of the created depset should be <i>compatible</i> with the order of "
              + "its <code>transitive</code> depsets. <code>\"default\"</code> order is compatible "
              + "with any other order, all other orders are only compatible with themselves."
              + "<p> Note on backward/forward compatibility. This function currently accepts a "
              + "positional <code>items</code> parameter. It is deprecated and will be removed "
              + "in the future, and after its removal <code>direct</code> will become a sole "
              + "positional parameter of the <code>depset</code> function. Thus, both of the "
              + "following calls are equivalent and future-proof:<br>"
              + "<pre class=language-python>"
              + "depset(['a', 'b'], transitive = [...])\n"
              + "depset(direct = ['a', 'b'], transitive = [...])\n"
              + "</pre>",
      parameters = {
        @Param(
            name = "items",
            type = Object.class,
            defaultValue = "[]",
            doc =
                "Deprecated: Either an iterable whose items become the direct elements of "
                    + "the new depset, in left-to-right order, or else a depset that becomes "
                    + "a transitive element of the new depset. In the latter case, "
                    + "<code>transitive</code> cannot be specified."),
        @Param(
            name = "order",
            type = String.class,
            defaultValue = "\"default\"",
            doc =
                "The traversal strategy for the new depset. See "
                    + "<a href=\"depset.html\">here</a> for the possible values."),
        @Param(
            name = "direct",
            type = SkylarkList.class,
            defaultValue = "None",
            positional = false,
            named = true,
            noneable = true,
            doc = "A list of <i>direct</i> elements of a depset."),
        @Param(
            name = "transitive",
            named = true,
            positional = false,
            type = SkylarkList.class,
            generic1 = SkylarkNestedSet.class,
            noneable = true,
            doc = "A list of depsets whose elements will become indirect elements of the depset.",
            defaultValue = "None")
      },
      useLocation = true)
  private static final BuiltinFunction depset =
      new BuiltinFunction("depset") {
        public SkylarkNestedSet invoke(
            Object items, String orderString, Object direct, Object transitive, Location loc)
            throws EvalException {
          Order order;
          try {
            order = Order.parse(orderString);
          } catch (IllegalArgumentException ex) {
            throw new EvalException(loc, ex);
          }

          if (transitive == Runtime.NONE && direct == Runtime.NONE) {
            // Legacy behavior.
            return SkylarkNestedSet.of(order, items, loc);
          }

          if (direct != Runtime.NONE && !isEmptySkylarkList(items)) {
            throw new EvalException(
                loc, "Do not pass both 'direct' and 'items' argument to depset constructor.");
          }

          // Non-legacy behavior: either 'transitive' or 'direct' were specified.
          Iterable<Object> directElements;
          if (direct != Runtime.NONE) {
            directElements = ((SkylarkList<?>) direct).getContents(Object.class, "direct");
          } else {
            SkylarkType.checkType(items, SkylarkList.class, "items");
            directElements = ((SkylarkList<?>) items).getContents(Object.class, "items");
          }

          Iterable<SkylarkNestedSet> transitiveList;
          if (transitive != Runtime.NONE) {
            SkylarkType.checkType(transitive, SkylarkList.class, "transitive");
            transitiveList =
                ((SkylarkList<?>) transitive).getContents(SkylarkNestedSet.class, "transitive");
          } else {
            transitiveList = ImmutableList.of();
          }
          SkylarkNestedSet.Builder builder = SkylarkNestedSet.builder(order, loc);
          for (Object directElement : directElements) {
            builder.addDirect(directElement);
          }
          for (SkylarkNestedSet transitiveSet : transitiveList) {
            builder.addTransitive(transitiveSet);
          }
          return builder.build();
        }
      };

  private static boolean isEmptySkylarkList(Object o) {
    return o instanceof SkylarkList && ((SkylarkList) o).isEmpty();
  }

  /**
   * Returns a function-value implementing "select" (i.e. configurable attributes) in the specified
   * package context.
   */
  @SkylarkSignature(
      name = "select",
      doc =
          "<code>select()</code> is the helper function that makes a rule attribute "
              + "<a href=\"$BE_ROOT/common-definitions.html#configurable-attributes\">"
              + "configurable</a>. See "
              + "<a href=\"$BE_ROOT/functions.html#select\">build encyclopedia</a> for details.",
      parameters = {
        @Param(name = "x", type = SkylarkDict.class, doc = "The parameter to convert."),
        @Param(
            name = "no_match_error",
            type = String.class,
            defaultValue = "''",
            doc = "Optional custom error to report if no condition matches.")
      },
      useLocation = true)
  private static final BuiltinFunction select =
      new BuiltinFunction("select") {
        public Object invoke(SkylarkDict<?, ?> dict, String noMatchError, Location loc)
            throws EvalException {
          for (Object key : dict.keySet()) {
            if (!(key instanceof String)) {
              throw new EvalException(
                  loc, String.format("Invalid key: %s. select keys must be label references", key));
            }
          }
          return SelectorList.of(new SelectorValue(dict, noMatchError));
        }
      };

  @SkylarkSignature(
      name = "zip",
      doc =
          "Returns a <code>list</code> of <code>tuple</code>s, where the i-th tuple contains "
              + "the i-th element from each of the argument sequences or iterables. The list has "
              + "the size of the shortest input. With a single iterable argument, it returns a "
              + "list of 1-tuples. With no arguments, it returns an empty list. Examples:"
              + "<pre class=\"language-python\">"
              + "zip()  # == []\n"
              + "zip([1, 2])  # == [(1,), (2,)]\n"
              + "zip([1, 2], [3, 4])  # == [(1, 3), (2, 4)]\n"
              + "zip([1, 2], [3, 4, 5])  # == [(1, 3), (2, 4)]</pre>",
      extraPositionals = @Param(name = "args", doc = "lists to zip."),
      returnType = MutableList.class,
      useLocation = true,
      useEnvironment = true)
  private static final BuiltinFunction zip =
      new BuiltinFunction("zip") {
        public MutableList<?> invoke(SkylarkList<?> args, Location loc, Environment env)
            throws EvalException {
          Iterator<?>[] iterators = new Iterator<?>[args.size()];
          for (int i = 0; i < args.size(); i++) {
            iterators[i] = EvalUtils.toIterable(args.get(i), loc, env).iterator();
          }
          ArrayList<Tuple<?>> result = new ArrayList<>();
          boolean allHasNext;
          do {
            allHasNext = !args.isEmpty();
            List<Object> elem = Lists.newArrayListWithExpectedSize(args.size());
            for (Iterator<?> iterator : iterators) {
              if (iterator.hasNext()) {
                elem.add(iterator.next());
              } else {
                allHasNext = false;
              }
            }
            if (allHasNext) {
              result.add(Tuple.copyOf(elem));
            }
          } while (allHasNext);
          return MutableList.wrapUnsafe(env, result);
        }
      };

  /** Skylark int type. */
  @SkylarkModule(
      name = "int",
      category = SkylarkModuleCategory.BUILTIN,
      doc =
          "A type to represent integers. It can represent any number between -2147483648 and "
              + "2147483647 (included). "
              + "Examples of int values:<br>"
              + "<pre class=\"language-python\">"
              + "153\n"
              + "0x2A  # hexadecimal literal\n"
              + "054  # octal literal\n"
              + "23 * 2 + 5\n"
              + "100 / -7\n"
              + "100 % -7  # -5 (unlike in some other languages)\n"
              + "int(\"18\")\n"
              + "</pre>")
  public static final class IntModule {}

  /** Skylark bool type. */
  @SkylarkModule(
      name = "bool",
      category = SkylarkModuleCategory.BUILTIN,
      doc =
          "A type to represent booleans. There are only two possible values: "
              + "<a href=\"globals.html#True\">True</a> and "
              + "<a href=\"globals.html#False\">False</a>. "
              + "Any value can be converted to a boolean using the "
              + "<a href=\"globals.html#bool\">bool</a> function.")
  public static final class BoolModule {}

  /** Adds bindings for all the builtin functions of this class to the given map builder. */
  public static void addBindingsToBuilder(ImmutableMap.Builder<String, Object> builder) {
    for (BaseFunction function : allFunctions) {
      builder.put(function.getName(), function);
    }
  }

  private static final ImmutableList<BaseFunction> allFunctions =
      ImmutableList.of(
          all, any, bool, depset, dict, dir, fail, getattr, hasattr, hash, enumerate, int_, len,
          list, max, min, print, range, repr, reversed, select, sorted, str, tuple, type, zip);

  static {
    SkylarkSignatureProcessor.configureSkylarkFunctions(MethodLibrary.class);
  }
}
