// 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.rules.java;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.BuildType;
import java.util.Collection;
import java.util.Map;

/**
 * Helpers for implementing rules which export Proguard specs.
 *
 * <p>This is not a ConfiguredTargetFactory; $proguard_library, which this class implements, is an
 * abstract rule class, and simply contributes this functionality to other rules.
 */
public final class ProguardLibrary {

  private static final String LOCAL_SPEC_ATTRIBUTE = "proguard_specs";
  private static final ImmutableMultimap<Mode, String> DEPENDENCY_ATTRIBUTES =
      ImmutableMultimap.<Mode, String>builder()
          .putAll(Mode.TARGET, "deps", "exports", "runtime_deps")
          .putAll(Mode.HOST, "plugins", "exported_plugins")
          .build();

  private final RuleContext ruleContext;

  /** Creates a new ProguardLibrary wrapping the given RuleContext. */
  public ProguardLibrary(RuleContext ruleContext) {
    this.ruleContext = ruleContext;
  }

  /** Collects the validated proguard specs exported by this rule and its dependencies. */
  public NestedSet<Artifact> collectProguardSpecs() {
    return collectProguardSpecs(DEPENDENCY_ATTRIBUTES);
  }

  /**
   * Collects the validated proguard specs exported by this rule and its dependencies through the
   * given attributes.
   */
  public NestedSet<Artifact> collectProguardSpecs(Multimap<Mode, String> attributes) {
    NestedSetBuilder<Artifact> specsBuilder = NestedSetBuilder.naiveLinkOrder();

    for (Map.Entry<Mode, String> attribute : attributes.entries()) {
      specsBuilder.addTransitive(
          collectProguardSpecsFromAttribute(attribute.getValue(), attribute.getKey()));
    }

    Collection<Artifact> localSpecs = collectLocalProguardSpecs();
    if (!localSpecs.isEmpty()) {
      // Pass our local proguard configs through the validator, which checks a whitelist.
      FilesToRunProvider proguardWhitelister =
          ruleContext.getExecutablePrerequisite("$proguard_whitelister", Mode.HOST);
      for (Artifact specToValidate : localSpecs) {
        specsBuilder.add(validateProguardSpec(proguardWhitelister, specToValidate));
      }
    }

    return specsBuilder.build();
  }

  /** Collects the unvalidated proguard specs exported by this rule. */
  public ImmutableList<Artifact> collectLocalProguardSpecs() {
    if (!ruleContext.attributes().has(LOCAL_SPEC_ATTRIBUTE, BuildType.LABEL_LIST)) {
      return ImmutableList.of();
    }
    return ruleContext.getPrerequisiteArtifacts(LOCAL_SPEC_ATTRIBUTE, Mode.TARGET).list();
  }

  /**
   * Collects the proguard specs exported by dependencies on the given LABEL_LIST/LABEL attribute.
   */
  private NestedSet<Artifact> collectProguardSpecsFromAttribute(String attributeName, Mode mode) {
    if (!ruleContext.attributes().has(attributeName, BuildType.LABEL_LIST)
        && !ruleContext.attributes().has(attributeName, BuildType.LABEL)) {
      return NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
    }
    NestedSetBuilder<Artifact> dependencySpecsBuilder = NestedSetBuilder.naiveLinkOrder();
    for (ProguardSpecProvider provider :
        ruleContext.getPrerequisites(attributeName, mode, ProguardSpecProvider.PROVIDER)) {
      dependencySpecsBuilder.addTransitive(provider.getTransitiveProguardSpecs());
    }
    return dependencySpecsBuilder.build();
  }

  /**
   * Creates an action to run the Proguard whitelister over the given Proguard spec and returns the
   * validated Proguard spec, ready to be exported.
   */
  private Artifact validateProguardSpec(
      FilesToRunProvider proguardWhitelister, Artifact specToValidate) {
    // If we're validating j/a/b/testapp/proguard.cfg, the output will be:
    // j/a/b/testapp/proguard.cfg_valid
    Artifact output =
        ruleContext.getUniqueDirectoryArtifact(
            "validated_proguard",
            specToValidate
                .getRootRelativePath()
                .replaceName(specToValidate.getFilename() + "_valid"),
            ruleContext.getBinOrGenfilesDirectory());
    ruleContext.registerAction(
        new SpawnAction.Builder()
            .addInput(specToValidate)
            .addOutput(output)
            .setExecutable(proguardWhitelister)
            .setProgressMessage("Validating proguard configuration")
            .setMnemonic("ValidateProguard")
            .addCommandLine(
                CustomCommandLine.builder()
                    .addExecPath("--path", specToValidate)
                    .addExecPath("--output", output)
                    .build())
            .build(ruleContext));
    return output;
  }
}
