// Copyright 2019 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.packages;

import static com.google.devtools.build.lib.packages.PackageFactory.getContext;

import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.License.DistributionType;
import com.google.devtools.build.lib.packages.PackageFactory.PackageContext;
import com.google.devtools.build.lib.packages.Type.ConversionException;
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.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.StarlarkThread;
import java.util.List;
import java.util.Set;

/** A global library of Starlark functions which are available only when evaluating BUILD files. */
@SkylarkGlobalLibrary
class StarlarkBuildLibrary {

  /**
   * Map of Starlark values (keyed by their symbol name) defined by this global library for use in
   * the global Starlark environment for BUILD files.
   */
  public static final ImmutableMap<String, Object> BINDINGS = initializeBindings();

  private static ImmutableMap<String, Object> initializeBindings() {
    ImmutableMap.Builder<String, Object> bindings = ImmutableMap.builder();
    Runtime.setupSkylarkLibrary(bindings, new StarlarkBuildLibrary());
    return bindings.build();
  }

  private StarlarkBuildLibrary() {
    // Not instantiable outside this class.
  }

  @SkylarkCallable(
      name = "environment_group",
      doc =
          "Defines a set of related environments that can be tagged onto rules to prevent"
              + "incompatible rules from depending on each other.",
      parameters = {
        @Param(
            name = "name",
            type = String.class,
            positional = false,
            named = true,
            doc = "The name of the rule."),
        // Both parameter below are lists of label designators
        @Param(
            name = "environments",
            type = SkylarkList.class,
            generic1 = Object.class,
            positional = false,
            named = true,
            doc = "A list of Labels for the environments to be grouped, from the same package."),
        @Param(
            name = "defaults",
            type = SkylarkList.class,
            generic1 = Object.class,
            positional = false,
            named = true,
            doc = "A list of Labels.")
      }, // TODO(bazel-team): document what that is
      // Not documented by docgen, as this is only available in BUILD files.
      // TODO(cparsons): Devise a solution to document BUILD functions.
      documented = false,
      useLocation = true,
      useStarlarkThread = true)
  public Runtime.NoneType environmentGroup(
      String name,
      SkylarkList<?> environmentsList, // <Label>
      SkylarkList<?> defaultsList, // <Label>
      Location loc,
      StarlarkThread thread)
      throws EvalException {
    PackageContext context = getContext(thread, loc);
    List<Label> environments =
        BuildType.LABEL_LIST.convert(
            environmentsList,
            "'environment_group argument'",
            context.pkgBuilder.getBuildFileLabel());
    List<Label> defaults =
        BuildType.LABEL_LIST.convert(
            defaultsList, "'environment_group argument'", context.pkgBuilder.getBuildFileLabel());

    if (environments.isEmpty()) {
      throw new EvalException(
          loc, "environment group " + name + " must contain at least one environment");
    }
    try {
      context.pkgBuilder.addEnvironmentGroup(
          name, environments, defaults, context.eventHandler, loc);
      return Runtime.NONE;
    } catch (LabelSyntaxException e) {
      throw new EvalException(
          loc, "environment group has invalid name: " + name + ": " + e.getMessage());
    } catch (Package.NameConflictException e) {
      throw new EvalException(loc, e.getMessage());
    }
  }

  @SkylarkCallable(
      name = "licenses",
      doc = "Declare the license(s) for the code in the current package.",
      parameters = {
        @Param(
            name = "license_strings",
            type = SkylarkList.class,
            generic1 = String.class,
            doc = "A list of strings, the names of the licenses used.")
      },
      // Not documented by docgen, as this is only available in BUILD files.
      // TODO(cparsons): Devise a solution to document BUILD functions.
      documented = false,
      useStarlarkThread = true,
      useLocation = true)
  public Runtime.NoneType invoke(
      SkylarkList<?> licensesList, // list of license strings
      Location loc,
      StarlarkThread thread)
      throws EvalException {
    PackageContext context = getContext(thread, loc);
    try {
      License license = BuildType.LICENSE.convert(licensesList, "'licenses' operand");
      context.pkgBuilder.setDefaultLicense(license);
    } catch (ConversionException e) {
      context.eventHandler.handle(Event.error(loc, e.getMessage()));
      context.pkgBuilder.setContainsErrors();
    }
    return Runtime.NONE;
  }

  @SkylarkCallable(
      name = "distribs",
      doc = "Declare the distribution(s) for the code in the current package.",
      parameters = {
        @Param(name = "distribution_strings", type = Object.class, doc = "The distributions.")
      },
      // Not documented by docgen, as this is only available in BUILD files.
      // TODO(cparsons): Devise a solution to document BUILD functions.
      documented = false,
      useStarlarkThread = true,
      useLocation = true)
  public Runtime.NoneType distribs(Object object, Location loc, StarlarkThread thread)
      throws EvalException {
    PackageContext context = getContext(thread, loc);

    try {
      Set<DistributionType> distribs =
          BuildType.DISTRIBUTIONS.convert(object, "'distribs' operand");
      context.pkgBuilder.setDefaultDistribs(distribs);
    } catch (ConversionException e) {
      context.eventHandler.handle(Event.error(loc, e.getMessage()));
      context.pkgBuilder.setContainsErrors();
    }
    return Runtime.NONE;
  }
}
