// 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.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
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. */
@SkylarkGlobalLibrary
public class MethodLibrary {

  @SkylarkCallable(
      name = "min",
      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)
  public Object min(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);
    }
  }

  @SkylarkCallable(
      name = "max",
      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)
  public Object max(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);
    }
  }

  @SkylarkCallable(
      name = "all",
      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,
            noneable = true,
            doc = "A string or a collection of elements.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public Boolean all(Object collection, Location loc, Environment env) throws EvalException {
    return !hasElementWithBooleanValue(collection, false, loc, env);
  }

  @SkylarkCallable(
      name = "any",
      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,
            noneable = true,
            doc = "A string or a collection of elements.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public Boolean any(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;
  }

  @SkylarkCallable(
      name = "sorted",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public MutableList<?> sorted(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);
    }
  }

  @SkylarkCallable(
      name = "reversed",
      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).",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
      },
      useLocation = true,
      useEnvironment = true)
  public MutableList<?> reversed(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);
  }

  @SkylarkCallable(
      name = "tuple",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public Tuple<?> tuple(Object x, Location loc, Environment env) throws EvalException {
    return Tuple.copyOf(EvalUtils.toCollection(x, loc, env));
  }

  @SkylarkCallable(
      name = "list",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public MutableList<?> list(Object x, Location loc, Environment env) throws EvalException {
    return MutableList.copyOf(env, EvalUtils.toCollection(x, loc, env));
  }

  @SkylarkCallable(
      name = "len",
      doc = "Returns the length of a string, list, tuple, depset, or dictionary.",
      parameters = {
        @Param(
            name = "x",
            doc = "The object to check length of.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public Integer len(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");
    }
  }

  @SkylarkCallable(
      name = "str",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      })
  public String str(Object x) {
    return Printer.str(x);
  }

  @SkylarkCallable(
      name = "repr",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      })
  public String repr(Object x) {
    return Printer.repr(x);
  }

  @SkylarkCallable(
      name = "bool",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      })
  public Boolean bool(Object x) throws EvalException {
    return EvalUtils.toBoolean(x);
  }

  private final ImmutableMap<String, Integer> intPrefixes =
      ImmutableMap.of("0b", 2, "0o", 8, "0x", 16);

  @SkylarkCallable(
      name = "int",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
        @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.",
            named = true)
      },
      useLocation = true)
  public Integer convertToInt(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;
  }

  @SkylarkCallable(
      name = "dict",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
      },
      extraKeywords = @Param(name = "kwargs", doc = "Dictionary of additional entries."),
      useLocation = true,
      useEnvironment = true)
  public SkylarkDict<?, ?> dict(
      Object args, SkylarkDict<?, ?> 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);
  }

  @SkylarkCallable(
      name = "enumerate",
      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 = {
        // Note Python uses 'sequence' keyword instead of 'list'. We may want to change tihs
        // some day.
        @Param(name = "list", type = SkylarkList.class, doc = "input list.", named = true)
      },
      useEnvironment = true)
  public MutableList<?> enumerate(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);
  }

  @SkylarkCallable(
      name = "hash",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      })
  public Integer hash(String value) throws EvalException {
    return value.hashCode();
  }

  @SkylarkCallable(
      name = "range",
      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",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
        @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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
        @Param(
            name = "step",
            type = Integer.class,
            defaultValue = "1",
            doc = "The increment (default is 1). It may be negative.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public SkylarkList<Integer> range(
      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. */
  @SkylarkCallable(
      name = "hasattr",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true),
        @Param(
            name = "name",
            type = String.class,
            doc = "The name of the attribute.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useEnvironment = true)
  public Boolean hasAttr(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);
  }

  @SkylarkCallable(
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true),
        @Param(
            name = "name",
            doc = "The name of the struct attribute.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
        @Param(
            name = "default",
            defaultValue = "unbound",
            doc =
                "The default value to return in case the struct "
                    + "doesn't have an attribute of the given name.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      },
      useLocation = true,
      useEnvironment = true)
  public Object getAttr(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;
  }

  @SkylarkCallable(
      name = "dir",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      },
      useLocation = true,
      useEnvironment = true)
  public MutableList<?> dir(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);
  }

  @SkylarkCallable(
      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.",
      parameters = {
        @Param(
            name = "msg",
            type = Object.class,
            doc = "Error to display for the user. The object is converted to a string.",
            defaultValue = "None",
            named = true,
            noneable = true),
        @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.",
            named = true)
      },
      useLocation = true)
  public Runtime.NoneType fail(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);
  }

  @SkylarkCallable(
      name = "print",
      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)
  public Runtime.NoneType print(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;
  }

  @SkylarkCallable(
      name = "type",
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      })
  public String type(Object object) {
    // There is no 'type' type in Skylark, so we return a string with the type name.
    return EvalUtils.getDataTypeName(object, false);
  }

  @SkylarkCallable(
      name = "depset",
      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.",
            named = true),
        @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.",
            named = true),
        @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)
  public SkylarkNestedSet depset(
      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.
   */
  @SkylarkCallable(
      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.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
        @Param(
            name = "no_match_error",
            type = String.class,
            defaultValue = "''",
            doc = "Optional custom error to report if no condition matches.",
            named = true)
      },
      useLocation = true)
  public Object select(SkylarkDict<?, ?> dict, String noMatchError, Location loc)
      throws EvalException {
    if (dict.isEmpty()) {
      throw new EvalException(
          loc,
          "select({}) with an empty dictionary can never resolve because it includes no conditions "
              + "to match");
    }
    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));
  }

  @SkylarkCallable(
      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."),
      useLocation = true,
      useEnvironment = true)
  public MutableList<?> zip(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"
              + "0o54  # 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) {
    Runtime.setupSkylarkLibrary(builder, new MethodLibrary());
  }
}
