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

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;

import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
 * Common functionality for tests for the constraint enforcement system.
 */
public abstract class AbstractConstraintsTest extends BuildViewTestCase {
  /**
   * Creates an environment group on the scratch filesystem consisting of the specified
   * environments and specified defaults, set via a builder-style interface. The package name
   * is the same as the group name.
   */
  protected class EnvironmentGroupMaker {
    private final String name;
    private Set<String> environments;
    private Set<String> defaults;
    private final Multimap<String, String> fulfillsMap = HashMultimap.create();

    public EnvironmentGroupMaker(String name) {
      this.name = name;
    }

    public EnvironmentGroupMaker setEnvironments(String... environments) {
      this.environments = ImmutableSet.copyOf(environments);
      return this;
    }

    public EnvironmentGroupMaker setDefaults(String... environments) {
      this.defaults = ImmutableSet.copyOf(environments);
      return this;
    }

    /**
     * Declares that env1 fulfills env2.
     */
    public EnvironmentGroupMaker setFulfills(String env1, String env2) {
      fulfillsMap.put(env1, env2);
      return this;
    }

    protected final void make() throws Exception {
      StringBuilder builder = new StringBuilder();
      for (String env : environments) {
        builder.append("environment(name = '" + env + "',\n")
            .append(getAttrDef("fulfills", fulfillsMap.get(env).toArray(new String[0])))
            .append(")\n");
      }
      builder.append("environment_group(\n")
          .append("    name = '" + name + "',\n")
          .append(getAttrDef("environments", environments.toArray(new String[0])) + ",\n")
          .append(getAttrDef("defaults", defaults.toArray(new String[0])) + ",\n")
          .append(")");
      scratch.file("" + name + "/BUILD", builder.toString());
    }
  }

  /**
   * Returns a rule definition of the given name, type and custom attribute settings.
   */
  protected static String getRuleDef(String ruleType, String ruleName, String... customAttributes) {
    String ruleDef =
        ruleType + "(\n"
        + "    name = '" + ruleName + "',\n"
        + "    srcs = ['" + ruleName + ".sh'],\n";
    for (String customAttribute : customAttributes) {
      ruleDef += "    " + customAttribute + ",\n";
    }
    ruleDef += ")\n";
    return ruleDef;
  }

  /**
   * Given the inputs, returns the string "attrName = [':label1', ':label2', etc.]"
   */
  protected static String getAttrDef(String attrName, String... labels) {
    String attrDef = "    " + attrName + " = [";
    for (String label : labels) {
      attrDef += "'" + label + "', ";
    }
    attrDef += "]";
    return attrDef;
  }

  /**
   * The core constraint semantics check that if rule A depends on rule B, B must support all of
   * A's environments. To model this in the tests below, we construct two rules: a "depending"
   * rule (i.e. A) that depends on a "dependency" rule (i.e. B). Each test can construct its
   * own instance of these rules with its own environments specifications by calling this method
   * and {@link #getDependencyRule} with appropriate environment settings passed in as custom
   * attributes.
   *
   * <p>This method constructs and returns the depending rule (i.e. A).
   */
  protected static String getDependingRule(String... customAttributes) {
    List<String> attrsAsList = Lists.newArrayList(customAttributes);
    attrsAsList.add(getAttrDef("deps", "dep"));
    return getRuleDef("sh_library", "main", attrsAsList.toArray(new String[0]));
  }

  /**
   * Returns the rule that {@link #getDependingRule} depends on. This rule must support every
   * environment supported by the other one for their constraint relationship to be considered
   * valid.
   */
  protected static String getDependencyRule(String... customAttributes) {
    return getRuleDef("sh_library", "dep", customAttributes);
  }

  /**
   * Returns the attribute definition that constrains a rule to the given environments. Inputs
   * are expected to be package-relative labels (e.g. {@code "foo_env"}).
   */
  protected static String constrainedTo(String... environments) {
    return getAttrDef("restricted_to", environments);
  }

  /**
   * Returns the attribute definition that designates a rule compatible with the given environments.
   */
  protected static String compatibleWith(String... environments) {
    return getAttrDef("compatible_with", environments);
  }

  /**
   * Returns the environments supported by a rule.
   */
  protected Collection<Label> supportedEnvironments(String ruleName, String ruleDef)
      throws Exception {
    return ConstraintSemantics.getSupportedEnvironments(
        getRuleContext(scratchConfiguredTarget("hello", ruleName, ruleDef))).getEnvironments();
  }
}
