// Copyright 2017 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.rules.objc;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.testutil.Scratch;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

/**
 * Provides utilities to help test a certain rule type without requiring the calling code to know
 * exactly what kind of rule is being tested. Only one instance is needed per rule type (e.g. one
 * instance for {@code objc_library}).
 */
public abstract class RuleType {
  /**
   * What to pass as the value of some attribute to indicate an attribute should not be added to the
   * rule. This can either be to test an error condition, or to use an alternative attribute to
   * supply the value.
   */
  public static final String OMIT_REQUIRED_ATTR = "<OMIT_REQUIRED_ATTR>";

  private final String ruleTypeName;

  RuleType(String ruleTypeName) {
    this.ruleTypeName = ruleTypeName;
  }

  /**
   * The name of this type as it appears in {@code BUILD} files, such as {@code objc_library}.
   */
  final String getRuleTypeName() {
    return ruleTypeName;
  }

  /**
   * Returns whether this type exports companion library target in Xcode.
   */
  final boolean exportsXcodeCompanionTarget() {
    return ruleTypeName.equals("objc_binary");
  }

  /**
   * Returns the bundle extension for the bundles generated by the rule.
   */
   final String bundleExtension() {
     return ruleTypeName.equals("ios_test") ? "xctest" : "app";
   }

  /**
   * Returns names and values, and otherwise prepares, extra attributes required for this rule type
   * to be without error. For instance, if this rule type requires 'srcs' and 'infoplist'
   * attributes, this method may be implemented as follows:
   * <pre>
   * {@code
   * List<String> attributes = new ArrayList<>();
   * if (!alreadyAdded.contains("srcs")) {
   *   scratch.file("/workspace_root/" + packageDir + "/a.m");
   *   attributes.add("srcs = ['a.m']");
   * }
   * if (!alreadyAdded.contains(INFOPLIST_ATTR)) {
   *   scratch.file("/workspace_root/" + packageDir + "Info.plist");
   *   attributes.add("infoplist = ['Info.plist']");
   * }
   * return attributes;
   * </pre>
   * }
   *
   * @throws IOException for whatever reason the implementator feels like, but mostly just when
   *     a scratch file couldn't be created
   */
  abstract Iterable<String> requiredAttributes(
      Scratch scratch, String packageDir, Set<String> alreadyAdded) throws IOException;

  private ImmutableMap<String, String> map(String... attrs) {
    ImmutableMap.Builder<String, String> map = new ImmutableMap.Builder<>();
    Preconditions.checkArgument((attrs.length & 1) == 0,
        "attrs must have an even number of elements");
    for (int i = 0; i < attrs.length; i += 2) {
      map.put(attrs[i], attrs[i + 1]);
    }
    return map.build();
  }

  /**
   * Generates the String necessary to define a target of this rule type.
   *
   * @param packageDir the package in which to create the target
   * @param name the name of the target
   * @param checkSpecificAttrs alternating name/values of attributes to add to the rule that are
   *     required for the check being performed to be defined a certain way. Pass
   *     {@link #OMIT_REQUIRED_ATTR} for a value to prevent an attribute from being automatically
   *     defined.
   */
  final String target(
      Scratch scratch, String packageDir, String name, String... checkSpecificAttrs)
      throws IOException {
    ImmutableMap<String, String> checkSpecific = map(checkSpecificAttrs);
    StringBuilder target = new StringBuilder(ruleTypeName)
        .append("(name = '")
        .append(name)
        .append("',");
    for (Map.Entry<String, String> entry : checkSpecific.entrySet()) {
      if (entry.getValue().equals(OMIT_REQUIRED_ATTR)) {
        continue;
      }
      target.append(entry.getKey())
          .append("=")
          .append(entry.getValue())
          .append(",");
    }
    Joiner.on(",").appendTo(
        target,
        requiredAttributes(scratch, packageDir, checkSpecific.keySet()));
    target.append(')');
    return target.toString();

  }

  /**
   * Creates a target at //x:x which is the only target in the BUILD file. Returns the string that
   * is written to the scratch file as it is often useful for debugging purposes.
   */
  public final String scratchTarget(Scratch scratch, String... checkSpecificAttrs)
      throws IOException {
    return scratchTarget("x", "x", scratch, checkSpecificAttrs);
  }

  /**
   * Creates a target at a given package which is the only target in the BUILD file. Returns the
   * string that is written to the scratch file as it is often useful for debugging purposes.
   *
   * @param packageDir the package of the target, for example "foo" in //foo:bar
   * @param targetName the name of the target, for example "bar" in //foo:bar
   * @param scratch the scratch object to use to create the build file
   * @param checkSpecificAttrs alternating name/values of attributes to add to the rule that are
   *     required for the check being performed to be defined a certain way. Pass
   *     {@link #OMIT_REQUIRED_ATTR} for a value to prevent an attribute from being automatically
   *     defined.
   */
  public final String scratchTarget(String packageDir, String targetName,
      Scratch scratch, String... checkSpecificAttrs)
      throws IOException {
    String target = target(scratch, packageDir, targetName, checkSpecificAttrs);
    scratch.file(packageDir + "/BUILD", starlarkLoadPrerequisites() + "\n" + target);
    return target;
  }

  /**
   * Returns a string (of one or more lines) required by BUILD files which reference targets of this
   * rule type.
   *
   * <p>Subclasses of {@link RuleType} should override this method if using the rule requires
   * Starlark files to be loaded.
   */
  public String starlarkLoadPrerequisites() {
    return "";
  }
}
