// 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.collect.ImmutableMap;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;

/**
 * Helper class used for expanding link references in rule and attribute documentation.
 *
 * <p>See {@link com.google.devtools.build.docgen.DocgenConsts.BLAZE_RULE_LINK} for the regex used
 * to match link references.
 */
// TODO(fwe): rename to LinkExpander
// TODO(fwe): prefix rule links with BE root?
public class RuleLinkExpander {
  private static final String EXAMPLES_SUFFIX = "_examples";
  private static final String ARGS_SUFFIX = "_args";
  private static final String IMPLICIT_OUTPUTS_SUFFIX = "_implicit_outputs";
  private static final String FUNCTIONS_PAGE = "functions";

  private static final ImmutableMap<String, String> FUNCTIONS =
      ImmutableMap.<String, String>builder()
          .put("load", FUNCTIONS_PAGE)
          .put("package", FUNCTIONS_PAGE)
          .put("package_group", FUNCTIONS_PAGE)
          .put("description", FUNCTIONS_PAGE)
          .put("distribs", FUNCTIONS_PAGE)
          .put("licenses", FUNCTIONS_PAGE)
          .put("exports_files", FUNCTIONS_PAGE)
          .put("glob", FUNCTIONS_PAGE)
          .put("select", FUNCTIONS_PAGE)
          .buildOrThrow();

  private final DocLinkMap linkMap;
  private final Map<String, String> ruleIndex = new HashMap<>();
  private final boolean singlePage;

  RuleLinkExpander(Map<String, String> ruleIndex, boolean singlePage, DocLinkMap linkMap) {
    this.ruleIndex.putAll(ruleIndex);
    this.ruleIndex.putAll(FUNCTIONS);
    this.singlePage = singlePage;
    this.linkMap = linkMap;
  }

  RuleLinkExpander(boolean singlePage, DocLinkMap linkMap) {
    this.ruleIndex.putAll(FUNCTIONS);
    this.singlePage = singlePage;
    this.linkMap = linkMap;
  }

  public String beRoot() {
    return linkMap.beRoot;
  }

  public void addIndex(Map<String, String> ruleIndex) {
    this.ruleIndex.putAll(ruleIndex);
  }

  private void appendRuleLink(Matcher matcher, StringBuffer sb, String ruleName, String ref) {
    String ruleFamily = ruleIndex.get(ruleName);
    String link =
        singlePage
            ? "#" + ref
            : Paths.get(linkMap.beRoot, String.format("%s.html#%s", ruleFamily, ref)).toString();
    matcher.appendReplacement(sb, Matcher.quoteReplacement(link));
  }

  /*
   * Match and replace all ${link rule.attribute} references.
   */
  private String expandRuleLinks(String htmlDoc) throws IllegalArgumentException {
    Matcher matcher = DocgenConsts.BLAZE_RULE_LINK.matcher(htmlDoc);
    StringBuffer sb = new StringBuffer(htmlDoc.length());
    while (matcher.find()) {
      // The first capture group matches the entire reference, e.g. "cc_binary.deps".
      String ref = matcher.group(1);
      // The second capture group only matches the rule name, e.g. "cc_binary" in "cc_binary.deps".
      String name = matcher.group(2);

      // The name in the reference is the name of a rule. Get the rule family for the rule and
      // replace the reference with a link with the form of rule-family.html#rule.attribute. For
      // example, ${link cc_library.deps} expands to c-cpp.html#cc_library.deps.
      if (ruleIndex.containsKey(name)) {
        appendRuleLink(matcher, sb, name, ref);
        continue;
      }

      // The name is referencing the examples, arguments, or implicit outputs of a rule (e.g.
      // "cc_library_args", "cc_library_examples", or "java_binary_implicit_outputs"). Strip the
      // suffix and then try matching the name to a rule family.
      if (name.endsWith(EXAMPLES_SUFFIX)
          || name.endsWith(ARGS_SUFFIX)
          || name.endsWith(IMPLICIT_OUTPUTS_SUFFIX)) {
        int endIndex;
        if (name.endsWith(EXAMPLES_SUFFIX)) {
          endIndex = name.indexOf(EXAMPLES_SUFFIX);
        } else if (name.endsWith(ARGS_SUFFIX)) {
          endIndex = name.indexOf(ARGS_SUFFIX);
        } else {
          endIndex = name.indexOf(IMPLICIT_OUTPUTS_SUFFIX);
        }
        String ruleName = name.substring(0, endIndex);
        if (ruleIndex.containsKey(ruleName)) {
          appendRuleLink(matcher, sb, ruleName, ref);
          continue;
        }
      }

      // The name is not the name of a rule but is the name of a static page, such as
      // common-definitions. Generate a link to that page.
      String mapping = linkMap.values.get(name);
      if (mapping != null) {
        String link = singlePage ? "#" + name : mapping;
        // For referencing headings on a static page, use the following syntax:
        // ${link static_page_name#heading_name}, example: ${link make-variables#gendir}
        String pageHeading = matcher.group(4);
        if (pageHeading != null) {
          throw new IllegalArgumentException(
              "Invalid link syntax for BE page: " + matcher.group()
              + "\nUse ${link static-page#heading} syntax instead.");
        }
        matcher.appendReplacement(sb, Matcher.quoteReplacement(link));
        continue;
      }

      // If the reference does not match any rule or static page, throw an exception.
      throw new IllegalArgumentException(
          "Rule family " + name + " in link tag does not match any rule or BE page: "
          + matcher.group());
    }
    matcher.appendTail(sb);
    return sb.toString();
  }

  /*
   * Match and replace all ${link rule#heading} references.
   */
  private String expandRuleHeadingLinks(String htmlDoc) throws IllegalArgumentException {
    Matcher matcher = DocgenConsts.BLAZE_RULE_HEADING_LINK.matcher(htmlDoc);
    StringBuffer sb = new StringBuffer(htmlDoc.length());
    while (matcher.find()) {
      // The first capture group matches the entire reference, e.g. "cc_library#some_heading".
      String ref = matcher.group(1);
      // The second capture group only matches the rule name, e.g. "cc_library" in
      // "cc_library#some_heading"
      String name = matcher.group(2);
      // The third capture group only matches the heading, e.g. "some_heading" in
      // "cc_library#some_heading"
      String heading = matcher.group(3);

      // The name in the reference is the name of a rule. Get the rule family for the rule and
      // replace the reference with the link in the form of rule-family.html#heading. Examples of
      // this include custom <a name="heading"> tags in the description or examples for the rule.
      if (ruleIndex.containsKey(name)) {
        String ruleFamily = ruleIndex.get(name);
        String link = singlePage
            ? "#" + heading
            : ruleFamily + ".html#" + heading;
        matcher.appendReplacement(sb, Matcher.quoteReplacement(link));
        continue;
      }

      // The name is of a static page, such as common.definitions. Generate a link to that page, and
      // append the page heading. For example, ${link common-definitions#label-expansion} expands to
      // common-definitions.html#label-expansion.

      // We need to search for the entire match first since some documentation files have a 1:n
      // relation between Blaze and Bazel. Example: build-ref#labels points to build-ref.html#labels
      // for Blaze, but to /concepts/labels for Bazel. However, we have to consider whether a single
      // heading or the entire page has to be redirected.

      // Not-null if page#heading has a mapping (other headings on the page are unaffected):
      String headingMapping = linkMap.values.get(ref);
      // Not-null if the entire page has a mapping, i.e. all headings should be redirected:
      String pageMapping = linkMap.values.get(name);

      if (headingMapping != null || pageMapping != null) {
        String link;
        if (singlePage) {
          // Special case: For the single-page BE we don't use the value of the mapping, we just
          // need to know that there is one (since that means `name` is a legitimate BE page).
          link = "#" + heading;
        } else if (headingMapping != null) {
          // Multi-page BE where page#heading has to be redirected.
          link = headingMapping;
        } else { // pageMapping != null
          // Multi-page BE where the entire page has to be forwarded (but the new page has
          // identical headings).
          link = String.format("%s#%s", pageMapping, heading);
        }

        matcher.appendReplacement(sb, Matcher.quoteReplacement(link));
        continue;
      }

      // If the reference does not match any rule or static page, throw an exception.
      throw new IllegalArgumentException(
          "Rule family " + name + " in link tag does not match any rule or BE page: "
          + matcher.group());
    }
    matcher.appendTail(sb);
    return sb.toString();
  }

  /**
   * Expands all rule references in the input HTML documentation.
   *
   * @param htmlDoc The input HTML documentation with ${link foo.bar} references.
   * @return The HTML documentation with all link references expanded.
   */
  public String expand(String htmlDoc) throws IllegalArgumentException {
    String expanded = expandRuleLinks(htmlDoc);
    return expandRuleHeadingLinks(expanded);
  }

  /**
   * Expands the rule reference.
   *
   * <p>This method is used to expand references in the BE velocity templates.
   *
   * @param ref The rule reference to expand.
   * @return The expanded rule reference.
   */
  public String expandRef(String ref) throws IllegalArgumentException {
    return expand("${link " + ref + "}");
  }
}
