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

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.docgen.DocgenConsts.RuleType;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.packages.RuleClass;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
 * A class representing the documentation of a rule along with some meta-data. The sole ruleName
 * field is used as a key for comparison, equals and hashcode.
 *
 * <p> The class contains meta information about the rule:
 * <ul>
 * <li> Rule type: categorizes the rule based on it's general (language independent) purpose,
 * see {@link RuleType}.
 * <li> Rule family: categorizes the rule based on language.
 * </ul>
 *
 * <p> The class also contains physical information about the documentation,
 * such as declaring file name and the first line of the raw documentation. This can be useful for
 * proper error signaling during documentation processing.
 */
public class RuleDocumentation implements Comparable<RuleDocumentation> {
  private final String ruleName;
  private final RuleType ruleType;
  private final String ruleFamily;
  private final String htmlDocumentation;
  // Store these information for error messages
  private final int startLineCount;
  private final String fileName;
  private final ImmutableSet<String> flags;

  private final Map<String, String> docVariables = new HashMap<>();
  // Only one attribute per attributeName is allowed
  private final Set<RuleDocumentationAttribute> attributes = new TreeSet<>();
  private final ConfiguredRuleClassProvider ruleClassProvider;

  private RuleLinkExpander linkExpander;

  /**
   * Name of the page documenting common build rule terms and concepts.
   */
  static final String COMMON_DEFINITIONS_PAGE = "common-definitions.html";

  /**
   * Creates a RuleDocumentation from the rule's name, type, family and raw html documentation
   * (meaning without expanding the variables in the doc).
   */
  RuleDocumentation(String ruleName, String ruleType, String ruleFamily,
      String htmlDocumentation, int startLineCount, String fileName, ImmutableSet<String> flags,
      ConfiguredRuleClassProvider ruleClassProvider) throws BuildEncyclopediaDocException {
    Preconditions.checkNotNull(ruleName);
    this.ruleName = ruleName;
    try {
      this.ruleType = RuleType.valueOf(ruleType);
    } catch (IllegalArgumentException e) {
      throw new BuildEncyclopediaDocException(
          fileName, startLineCount, "Invalid rule type " + ruleType);
    }
    this.ruleFamily = ruleFamily;
    this.htmlDocumentation = htmlDocumentation;
    this.startLineCount = startLineCount;
    this.fileName = fileName;
    this.flags = flags;
    this.ruleClassProvider = ruleClassProvider;
  }

  /**
   * Returns the name of the rule.
   */
  public String getRuleName() {
    return ruleName;
  }

  /**
   * Returns the type of the rule
   */
  RuleType getRuleType() {
    return ruleType;
  }

  /**
   * Returns the family of the rule. The family is usually the corresponding programming language,
   * except for rules independent of language, such as genrule. E.g. the family of the java_library
   * rule is 'JAVA', the family of genrule is 'GENERAL'.
   */
  String getRuleFamily() {
    return ruleFamily;
  }

  /**
   * Returns a "normalized" version of the input string. Used to convert rule family names into
   * strings that are more friendly as file names. For example, "C / C++" is converted to
   * "c-cpp".
   */
  @VisibleForTesting
  static String normalize(String s) {
    return s.toLowerCase()
        .replace("+", "p")
        .replaceAll("[()]", "")
        .replaceAll("[\\s/]", "-")
        .replaceAll("[-]+", "-");
  }

  /**
   * Returns the number of first line of the rule documentation in its declaration file.
   */
  int getStartLineCount() {
    return startLineCount;
  }

  /**
   * Returns true if this rule documentation has the parameter flag.
   */
  boolean hasFlag(String flag) {
    return flags.contains(flag);
  }

  /**
   * Returns true if this rule applies to a specific programming language (e.g. java_library),
   * returns false if it is a generic action (e.g. genrule, filegroup).
   *
   * <p>A rule is considered to be specific to a programming language by default. Generic rules
   * have to be marked with the flag GENERIC_RULE in their #BLAZE_RULE definition.
   */
  boolean isLanguageSpecific() {
    return !flags.contains(DocgenConsts.FLAG_GENERIC_RULE);
  }

  /**
   * Adds a variable name - value pair to the documentation to be substituted.
   */
  void addDocVariable(String varName, String value) {
    docVariables.put(varName, value);
  }

  /**
   * Adds a rule documentation attribute to this rule documentation.
   */
  void addAttribute(RuleDocumentationAttribute attribute) {
    attributes.add(attribute);
  }

  /**
   * Returns the rule's set of RuleDocumentationAttributes.
   */
  public Set<RuleDocumentationAttribute> getAttributes() {
    return attributes;
  }

  /**
   * Sets the {@link RuleLinkExpander} to be used to expand links in the HTML documentation for
   * both this RuleDocumentation and all {@link RuleDocumentationAttribute}s associated with this
   * rule.
   */
  public void setRuleLinkExpander(RuleLinkExpander linkExpander) {
    this.linkExpander = linkExpander;
    for (RuleDocumentationAttribute attribute : attributes) {
      attribute.setRuleLinkExpander(linkExpander);
    }
  }

  /**
   * Returns the html documentation in the exact format it should be written into the Build
   * Encyclopedia (expanding variables).
   */
  public String getHtmlDocumentation() throws BuildEncyclopediaDocException {
    String expandedDoc = htmlDocumentation;
    // Substituting variables
    for (Map.Entry<String, String> docVariable : docVariables.entrySet()) {
      expandedDoc = expandedDoc.replace("${" + docVariable.getKey() + "}",
          expandBuiltInVariables(docVariable.getKey(), docVariable.getValue()));
    }
    if (linkExpander != null) {
      try {
        expandedDoc = linkExpander.expand(expandedDoc);
      } catch (IllegalArgumentException e) {
        throw new BuildEncyclopediaDocException(fileName, startLineCount, e.getMessage());
      }
    }
    return expandedDoc;
  }

  /**
   * Returns the documentation of the rule in a form which is printable on the command line.
   */
  String getCommandLineDocumentation() {
    return "\n" + DocgenConsts.toCommandLineFormat(htmlDocumentation);
  }

  /**
   * Returns a string containing any extra documentation for the name attribute for this
   * rule.
   */
  public String getNameExtraHtmlDoc() throws BuildEncyclopediaDocException {
    String expandedDoc = docVariables.containsKey(DocgenConsts.VAR_NAME)
        ? docVariables.get(DocgenConsts.VAR_NAME)
        : "";
    if (linkExpander != null) {
      try {
        expandedDoc = linkExpander.expand(expandedDoc);
      } catch (IllegalArgumentException e) {
        throw new BuildEncyclopediaDocException(fileName, startLineCount, e.getMessage());
      }
    }
    return expandedDoc;
  }

  /**
   * Returns whether this rule has public visibility by default.
   */
  public boolean isPublicByDefault() {
    RuleClass ruleClass = ruleClassProvider.getRuleClassMap().get(ruleName);
    return ruleClass != null && ruleClass.isPublicByDefault();
  }

  /**
   * Returns whether this rule is deprecated.
   */
  public boolean isDeprecated() {
    return hasFlag(DocgenConsts.FLAG_DEPRECATED);
  }

  /**
   * Returns a string containing the attribute signature for this rule with HTML links
   * to the attributes.
   */
  public String getAttributeSignature() {
    StringBuilder sb = new StringBuilder();
    sb.append(String.format("%s(<a href=\"#%s.name\">name</a>, ", ruleName, ruleName));
    int i = 0;
    for (RuleDocumentationAttribute attributeDoc : attributes) {
      String attrName = attributeDoc.getAttributeName();
      // Generate the link for the attribute documentation
      if (attributeDoc.isCommonType()) {
        sb.append(String.format("<a href=\"%s#%s.%s\">%s</a>",
            COMMON_DEFINITIONS_PAGE,
            attributeDoc.getGeneratedInRule(ruleName).toLowerCase(),
            attrName,
            attrName));
      } else {
        sb.append(String.format("<a href=\"#%s.%s\">%s</a>",
            attributeDoc.getGeneratedInRule(ruleName).toLowerCase(),
            attrName,
            attrName));
      }
      if (i < attributes.size() - 1) {
        sb.append(", ");
      } else {
        sb.append(")");
      }
      i++;
    }
    return sb.toString();
  }

  private String expandBuiltInVariables(String key, String value) {
    // Some built in BLAZE variables need special handling, e.g. adding headers
    switch (key) {
      case DocgenConsts.VAR_IMPLICIT_OUTPUTS:
        return String.format("<h4 id=\"%s_implicit_outputs\">Implicit output targets</h4>\n%s",
            ruleName.toLowerCase(), value);
      default:
        return value;
    }
  }

  /**
   * Returns a set of examples based on markups which can be used as BUILD file
   * contents for testing.
   */
  Set<String> extractExamples() throws BuildEncyclopediaDocException {
    String[] lines = htmlDocumentation.split(DocgenConsts.LS);
    Set<String> examples = new HashSet<>();
    StringBuilder sb = null;
    boolean inExampleCode = false;
    int lineCount = 0;
    for (String line : lines) {
      if (!inExampleCode) {
        if (DocgenConsts.BLAZE_RULE_EXAMPLE_START.matcher(line).matches()) {
          inExampleCode = true;
          sb = new StringBuilder();
        } else if (DocgenConsts.BLAZE_RULE_EXAMPLE_END.matcher(line).matches()) {
          throw new BuildEncyclopediaDocException(fileName, startLineCount + lineCount,
              "No matching start example tag (#BLAZE_RULE.EXAMPLE) for end example tag.");
        }
      } else {
        if (DocgenConsts.BLAZE_RULE_EXAMPLE_END.matcher(line).matches()) {
          inExampleCode = false;
          examples.add(sb.toString());
          sb = null;
        } else if (DocgenConsts.BLAZE_RULE_EXAMPLE_START.matcher(line).matches()) {
          throw new BuildEncyclopediaDocException(fileName, startLineCount + lineCount,
              "No start example tags (#BLAZE_RULE.EXAMPLE) in a row.");
        } else {
          sb.append(line + DocgenConsts.LS);
        }
      }
      lineCount++;
    }
    return examples;
  }

  /**
   * Creates a BuildEncyclopediaDocException with the file containing this rule doc and
   * the number of the first line (where the rule doc is defined). Can be used to create
   * general BuildEncyclopediaDocExceptions about this rule.
   */
  BuildEncyclopediaDocException createException(String msg) {
    return new BuildEncyclopediaDocException(fileName, startLineCount, msg);
  }

  @Override
  public int hashCode() {
    return ruleName.hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof RuleDocumentation)) {
      return false;
    }
    return ruleName.equals(((RuleDocumentation) obj).ruleName);
  }

  private int getTypePriority() {
    switch (ruleType) {
      case BINARY:
        return 1;
      case LIBRARY:
        return 2;
      case TEST:
        return 3;
      case OTHER:
        return 4;
    }
    throw new IllegalArgumentException("Illegal value of ruleType: " + ruleType);
  }

  @Override
  public int compareTo(RuleDocumentation o) {
    if (this.getTypePriority() < o.getTypePriority()) {
      return -1;
    } else if (this.getTypePriority() > o.getTypePriority()) {
      return 1;
    } else {
      return this.ruleName.compareTo(o.ruleName);
    }
  }

  @Override
  public String toString() {
    return String.format("%s (TYPE = %s, FAMILY = %s)", ruleName, ruleType, ruleFamily);
  }
}
