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

import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.packages.Type.LabelClass;
import com.google.devtools.build.lib.packages.Type.ListType;
import com.google.devtools.build.lib.util.FileTypeSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * A helper class to generate valid rules with filled attributes if necessary.
 */
public class BuildRuleWithDefaultsBuilder extends BuildRuleBuilder {

  private Set<String> generateFiles;
  private Map<String, BuildRuleBuilder> generateRules;

  public BuildRuleWithDefaultsBuilder(String ruleClass, String ruleName) {
    super(ruleClass, ruleName);
    this.generateFiles = new HashSet<>();
    this.generateRules = new HashMap<>();
  }

  private BuildRuleWithDefaultsBuilder(String ruleClass, String ruleName,
      Map<String, RuleClass> ruleClassMap, Set<String> generateFiles,
      Map<String, BuildRuleBuilder> generateRules) {
    super(ruleClass, ruleName, ruleClassMap);
    this.generateFiles = generateFiles;
    this.generateRules = generateRules;
  }

  /**
   * Creates a dummy file with the given extension in the given package and returns a valid Blaze
   * label referring to the file. Note, the created label depends on the package of the rule.
   */
  private String getDummyFileLabel(String rulePkg, String filePkg, String extension,
      Type<?> attrType) {
    boolean isOutput = attrType.getLabelClass() == LabelClass.OUTPUT;
    String fileName = (isOutput ? "dummy_output" : "dummy_input") + extension;
    generateFiles.add(filePkg + "/" + fileName);
    if (rulePkg.equals(filePkg)) {
      return ":" + fileName;
    } else {
      return filePkg + ":" + fileName;
    }
  }

  private String getDummyRuleLabel(String rulePkg, RuleClass referencedRuleClass) {
    String referencedRuleName = ruleName + "_ref_" + referencedRuleClass.getName()
        .replace("$", "").replace(":", "");
    // The new generated rule should have the same generatedFiles and generatedRules
    // in order to avoid duplications
    BuildRuleWithDefaultsBuilder builder = new BuildRuleWithDefaultsBuilder(
        referencedRuleClass.getName(), referencedRuleName, ruleClassMap, generateFiles,
        generateRules);
    builder.populateAttributes(rulePkg, true);
    generateRules.put(referencedRuleClass.getName(), builder);
    return referencedRuleName;
  }

  public BuildRuleWithDefaultsBuilder populateLabelAttribute(String pkg, Attribute attribute) {
    return populateLabelAttribute(pkg, pkg, attribute);
  }

  /**
   * Populates the label type attribute with generated values. Populates with a file if possible, or
   * generates an appropriate rule. Note, that the rules are always generated in the same package.
   */
  @CanIgnoreReturnValue
  public BuildRuleWithDefaultsBuilder populateLabelAttribute(
      String rulePkg, String filePkg, Attribute attribute) {
    Type<?> attrType = attribute.getType();
    String label = null;
    if (attribute.getAllowedFileTypesPredicate() != FileTypeSet.NO_FILE) {
      // Try to populate with files first
      String extension = "";
      if (attribute.getAllowedFileTypesPredicate() == FileTypeSet.ANY_FILE) {
        extension = ".txt";
      } else if (attribute.getAllowedFileTypesPredicate() != null) {
        FileTypeSet fileTypes = attribute.getAllowedFileTypesPredicate();
        // This argument should always hold, if not that means a Blaze design/implementation error
        Preconditions.checkArgument(
            !fileTypes.getExtensions().isEmpty(),
            "Attribute %s does not have any allowed file types",
            attribute.getName());
        extension = fileTypes.getExtensions().get(0);
      }
      label = getDummyFileLabel(rulePkg, filePkg, extension, attrType);
    } else {
      Predicate<RuleClass> allowedRuleClasses = attribute.getAllowedRuleClassesPredicate();
      if (allowedRuleClasses != Predicates.<RuleClass>alwaysFalse()) {
        // See if there is an applicable rule among the already enqueued rules
        BuildRuleBuilder referencedRuleBuilder = getFirstApplicableRule(attribute);
        if (referencedRuleBuilder != null) {
          label = ":" + referencedRuleBuilder.ruleName;
        } else {
          RuleClass referencedRuleClass = getFirstApplicableRuleClass(attribute);
          if (referencedRuleClass != null) {
            // Generate a rule with the appropriate ruleClass and a label for it in
            // the original rule
            label = ":" + getDummyRuleLabel(rulePkg, referencedRuleClass);
          }
        }
      }
    }
    if (label != null) {
      if (attrType instanceof ListType<?>) {
        addMultiValueAttributes(attribute.getName(), label);
      } else {
        setSingleValueAttribute(attribute.getName(), label);
      }
    }
    return this;
  }

  private boolean doesRuleClassMatch(Attribute attribute, RuleClass ruleClass) {
    // The rule class isn't in the allowed list.
    if (!attribute.getAllowedRuleClassesPredicate().apply(ruleClass)) {
      return false;
    }

    // Does this rule class have the correct providers?
    if (!attribute.getRequiredProviders().acceptsAny()) {
      // This attribute requires specific providers, so ignore any rule that claims to have every
      // provider.
      if (ruleClass.getAdvertisedProviders().canHaveAnyProvider()) {
        return false;
      }

      if (!attribute.getRequiredProviders().isSatisfiedBy(ruleClass.getAdvertisedProviders())) {
        return false;
      }
    }

    // Default to accept if nothing else prevents.
    return true;
  }

  private BuildRuleBuilder getFirstApplicableRule(Attribute attribute) {
    // There is no direct way to get the set of allowedRuleClasses from the Attribute
    // The Attribute API probably should not be modified for sole testing purposes
    Optional<BuildRuleBuilder> result =
        generateRules.entrySet().stream()
            .filter(entry -> doesRuleClassMatch(attribute, ruleClassMap.get(entry.getKey())))
            .map(Map.Entry::getValue)
            .findFirst();
    return result.orElse(null);
  }

  private RuleClass getFirstApplicableRuleClass(Attribute attribute) {
    Optional<RuleClass> result =
        ruleClassMap.values().stream()
            .filter(ruleClass -> doesRuleClassMatch(attribute, ruleClass))
            .findFirst();
    return result.orElse(null);
  }

  @CanIgnoreReturnValue
  public BuildRuleWithDefaultsBuilder populateStringListAttribute(Attribute attribute) {
    addMultiValueAttributes(attribute.getName(), "x");
    return this;
  }

  @CanIgnoreReturnValue
  public BuildRuleWithDefaultsBuilder populateStringAttribute(Attribute attribute) {
    setSingleValueAttribute(attribute.getName(), "x");
    return this;
  }

  @CanIgnoreReturnValue
  public BuildRuleWithDefaultsBuilder populateBooleanAttribute(Attribute attribute) {
    setSingleValueAttribute(attribute.getName(), "false");
    return this;
  }

  @CanIgnoreReturnValue
  public BuildRuleWithDefaultsBuilder populateIntegerAttribute(Attribute attribute) {
    setSingleValueAttribute(attribute.getName(), 1);
    return this;
  }

  @CanIgnoreReturnValue
  public BuildRuleWithDefaultsBuilder populateAttributes(String rulePkg, boolean heuristics) {
    for (Attribute attribute : ruleClass.getAttributes()) {
      if (attribute.isMandatory()) {
        if (BuildType.isLabelType(attribute.getType())) {
          // TODO(bazel-team): actually an empty list would be fine in the case where
          // attribute instanceof ListType && !attribute.isNonEmpty(), but BuildRuleBuilder
          // doesn't support that, and it makes little sense anyway
          populateLabelAttribute(rulePkg, attribute);
        } else {
          // Non label type attributes
          if (attribute.getAllowedValues() instanceof AllowedValueSet) {
            Collection<Object> allowedValues =
                ((AllowedValueSet) attribute.getAllowedValues()).getAllowedValues();
            setSingleValueAttribute(attribute.getName(), allowedValues.iterator().next());
          } else if (attribute.getType() == Type.STRING) {
            populateStringAttribute(attribute);
          } else if (attribute.getType() == Type.BOOLEAN) {
            populateBooleanAttribute(attribute);
          } else if (attribute.getType() == Type.INTEGER) {
            populateIntegerAttribute(attribute);
          } else if (attribute.getType() == Type.STRING_LIST) {
            populateStringListAttribute(attribute);
          }
        }
        // TODO(bazel-team): populate for other data types
      } else if (heuristics) {
        populateAttributesHeuristics(rulePkg, attribute);
      }
    }
    return this;
  }

  // Heuristics which might help to generate valid rules.
  // This is a bit hackish, but it helps some generated ruleclasses to pass analysis phase.
  private void populateAttributesHeuristics(String rulePkg, Attribute attribute) {
    if (attribute.getName().equals("srcs") && attribute.getType() == BuildType.LABEL_LIST) {
      // If there is a srcs attribute it might be better to populate it even if it's not mandatory
      populateLabelAttribute(rulePkg, attribute);
    } else if (attribute.getName().equals("main_class") && attribute.getType() == Type.STRING) {
      populateStringAttribute(attribute);
    }
  }

  @Override
  public Collection<String> getFilesToGenerate() {
    return generateFiles;
  }

  @Override
  public Collection<BuildRuleBuilder> getRulesToGenerate() {
    return generateRules.values();
  }
}
