// 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.pkgcache;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.FileTarget;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.RawAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * A helper class for getting source and header files from a given {@link Rule}.
 */
public final class SrcTargetUtil {
  private SrcTargetUtil() {
  }

  /**
   * Given a Rule, returns an immutable list of FileTarget for its sources, in the order they appear
   * in its "srcs", "src" or "srcjar" attribute, and any filegroups or other rules it references.
   * An empty list is returned if no "srcs" or "src" attribute exists for this rule. The list may
   * contain OutputFiles if the sources were generated by another rule.
   *
   * <p>This method should be considered only a heuristic, and should not be used during the
   * analysis phase.
   *
   * <p>(We could remove the throws clauses if we restrict the results to srcs within the same
   * package.)
   *
   * @throws NoSuchTargetException or NoSuchPackageException when a source label cannot be resolved
   *         to a Target
   */
  @ThreadSafety.ThreadSafe
  public static List<FileTarget> getSrcTargets(EventHandler eventHandler, Rule rule,
                                               TargetProvider provider)
      throws NoSuchTargetException, NoSuchPackageException, InterruptedException  {
    return getTargets(eventHandler, rule, SOURCE_ATTRIBUTES, Sets.newHashSet(rule.getLabel()),
        provider);
  }

  // Attributes referring to "sources".
  private static final ImmutableSet<String> SOURCE_ATTRIBUTES =
      ImmutableSet.of("srcs", "src", "srcjar");

  // The attribute to search in filegroups.
  private static final ImmutableSet<String> FILEGROUP_ATTRIBUTES =
      ImmutableSet.of("srcs");

  /**
   * @see #getSrcTargets(EventHandler, Rule, TargetProvider)
   */
  private static List<FileTarget> getTargets(EventHandler eventHandler,
      Rule rule,
      ImmutableSet<String> attributes,
      Set<Label> visitedRuleLabels,
      TargetProvider targetProvider)
      throws NoSuchTargetException, NoSuchPackageException, InterruptedException {
    List<Label> srcLabels = Lists.newArrayList();
    RawAttributeMapper attributeMapper = RawAttributeMapper.of(rule);
    for (String attrName : attributes) {
      if (rule.isAttrDefined(attrName, BuildType.LABEL_LIST)) {
        // Note that we simply flatten configurable attributes here, which is not the correct
        // behavior. However, it seems to be a good approximation of what is needed in most use
        // cases.
        srcLabels.addAll(attributeMapper.getMergedValues(attrName, BuildType.LABEL_LIST));
      } else if (rule.isAttrDefined(attrName, BuildType.LABEL)
          && !rule.isConfigurableAttribute(attrName)) {
        Label srcLabel = attributeMapper.get(attrName, BuildType.LABEL);
        if (srcLabel != null) {
          srcLabels.add(srcLabel);
        }
      }
    }
    if (srcLabels.isEmpty()) {
      return ImmutableList.of();
    }
    List<FileTarget> srcTargets = new ArrayList<>();
    for (Label label : srcLabels) {
      Target target = targetProvider.getTarget(eventHandler, label);
      if (target instanceof FileTarget) {
        srcTargets.add((FileTarget) target);
      } else {
        Rule srcRule = target.getAssociatedRule();
        if (srcRule != null && !visitedRuleLabels.contains(srcRule.getLabel())) {
          visitedRuleLabels.add(srcRule.getLabel());
          if ("filegroup".equals(srcRule.getRuleClass())) {
            srcTargets.addAll(getTargets(eventHandler, srcRule, FILEGROUP_ATTRIBUTES,
                visitedRuleLabels, targetProvider));
          } else {
            srcTargets.addAll(srcRule.getOutputFiles());
          }
        }
      }
    }
    return ImmutableList.copyOf(srcTargets);
  }
}
