// 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.common.options;

import com.google.common.base.Ascii;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.escape.Escaper;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;

/** A renderer for usage messages for any combination of options classes. */
class OptionsUsage {

  private static final Splitter NEWLINE_SPLITTER = Splitter.on('\n');
  private static final Joiner COMMA_JOINER = Joiner.on(",");

  /**
   * Given an options class, render the usage string into the usage, which is passed in as an
   * argument. This will not include information about expansions for options using expansion
   * functions (it would be unsafe to report this as we cannot know what options from other {@link
   * OptionsBase} subclasses they depend on until a complete parser is constructed).
   */
  static void getUsage(Class<? extends OptionsBase> optionsClass, StringBuilder usage) {
    OptionsData data = OptionsParser.getOptionsDataInternal(optionsClass);
    List<OptionDefinition> optionDefinitions =
        new ArrayList<>(OptionsData.getAllOptionDefinitionsForClass(optionsClass));
    optionDefinitions.sort(OptionDefinition.BY_OPTION_NAME);
    for (OptionDefinition optionDefinition : optionDefinitions) {
      getUsage(optionDefinition, usage, OptionsParser.HelpVerbosity.LONG, data, false);
    }
  }

  /** Appends the usage message for a single option-field message to 'usage'. */
  static void getUsage(
      OptionDefinition optionDefinition,
      StringBuilder usage,
      OptionsParser.HelpVerbosity helpVerbosity,
      OptionsData optionsData,
      boolean includeTags) {
    String flagName = getFlagName(optionDefinition);
    String typeDescription = getTypeDescription(optionDefinition);
    usage.append("  --").append(flagName);
    if (helpVerbosity == OptionsParser.HelpVerbosity.SHORT) {
      usage.append('\n');
      return;
    }

    // Add the option's type and default information. Stop there for "medium" verbosity.
    if (optionDefinition.getAbbreviation() != '\0') {
      usage.append(" [-").append(optionDefinition.getAbbreviation()).append(']');
    }
    if (!typeDescription.isEmpty()) {
      usage.append(" (").append(typeDescription).append("; ");
      if (optionDefinition.allowsMultiple()) {
        usage.append("may be used multiple times");
      } else {
        // Don't call the annotation directly (we must allow overrides to certain defaults)
        String defaultValueString = optionDefinition.getUnparsedDefaultValue();
        if (optionDefinition.isSpecialNullDefault()) {
          usage.append("default: see description");
        } else {
          usage.append("default: \"").append(defaultValueString).append("\"");
        }
      }
      usage.append(")");
    }
    usage.append("\n");
    if (helpVerbosity == OptionsParser.HelpVerbosity.MEDIUM) {
      return;
    }

    // For verbosity "long," add the full description and expansion, along with the tag
    // information if requested.
    if (!optionDefinition.getHelpText().isEmpty()) {
      usage.append(paragraphFill(optionDefinition.getHelpText(), /*indent=*/ 4, /*width=*/ 80));
      usage.append('\n');
    }
    ImmutableList<String> expansion = getExpansionIfKnown(optionDefinition, optionsData);
    if (expansion == null) {
      usage.append(paragraphFill("Expands to unknown options.", /*indent=*/ 6, /*width=*/ 80));
      usage.append('\n');
    } else if (!expansion.isEmpty()) {
      StringBuilder expandsMsg = new StringBuilder("Expands to: ");
      for (String exp : expansion) {
        expandsMsg.append(exp).append(" ");
      }
      usage.append(paragraphFill(expandsMsg.toString(), /*indent=*/ 6, /*width=*/ 80));
      usage.append('\n');
    }
    if (optionDefinition.hasImplicitRequirements()) {
      StringBuilder requiredMsg = new StringBuilder("Using this option will also add: ");
      for (String req : optionDefinition.getImplicitRequirements()) {
        requiredMsg.append(req).append(" ");
      }
      usage.append(paragraphFill(requiredMsg.toString(), 6, 80)); // (indent, width)
      usage.append('\n');
    }
    if (!includeTags) {
      return;
    }

    // If we are expected to include the tags, add them for high verbosity.
    Stream<OptionEffectTag> effectTagStream =
        Arrays.stream(optionDefinition.getOptionEffectTags())
            .filter(OptionsUsage::shouldEffectTagBeListed);
    Stream<OptionMetadataTag> metadataTagStream =
        Arrays.stream(optionDefinition.getOptionMetadataTags())
            .filter(OptionsUsage::shouldMetadataTagBeListed);
    String tagList =
        Stream.concat(effectTagStream, metadataTagStream)
            .map(tag -> Ascii.toLowerCase(tag.toString()))
            .collect(Collectors.joining(", "));
    if (!tagList.isEmpty()) {
      usage.append(paragraphFill("Tags: " + tagList, 6, 80)); // (indent, width)
      usage.append("\n");
    }
  }

  /**
   * Paragraph-fill the specified input text, indenting lines to 'indent' and
   * wrapping lines at 'width'.  Returns the formatted result.
   */
  static String paragraphFill(String in, int indent, int width) {
    String indentString = " ".repeat(indent);
    StringBuilder out = new StringBuilder();
    String sep = "";
    for (String paragraph : NEWLINE_SPLITTER.split(in)) {
      // TODO(ccalvarin) break iterators expect hyphenated words to be line-breakable, which looks
      // funny for --flag
      BreakIterator boundary = BreakIterator.getLineInstance(); // (factory)
      boundary.setText(paragraph);
      out.append(sep).append(indentString);
      int cursor = indent;
      for (int start = boundary.first(), end = boundary.next();
           end != BreakIterator.DONE;
           start = end, end = boundary.next()) {
        String word =
            paragraph.substring(start, end); // (may include trailing space)
        if (word.length() + cursor > width) {
          out.append('\n').append(indentString);
          cursor = indent;
        }
        out.append(word);
        cursor += word.length();
      }
      sep = "\n";
    }
    return out.toString();
  }

  /**
   * Returns the expansion for an option, if any, regardless of if the expansion is from a function
   * or is statically declared in the annotation.
   */
  @Nullable
  private static ImmutableList<String> getExpansionIfKnown(
      OptionDefinition optionDefinition, OptionsData optionsData) {
    Preconditions.checkNotNull(optionDefinition);
    return optionsData.getEvaluatedExpansion(optionDefinition);
  }

  // Placeholder tag "UNKNOWN" is ignored.
  private static boolean shouldEffectTagBeListed(OptionEffectTag effectTag) {
    return !effectTag.equals(OptionEffectTag.UNKNOWN);
  }

  // Tags that only apply to undocumented options are excluded.
  private static boolean shouldMetadataTagBeListed(OptionMetadataTag metadataTag) {
    return !metadataTag.equals(OptionMetadataTag.HIDDEN)
        && !metadataTag.equals(OptionMetadataTag.INTERNAL);
  }

  /** Append the usage message for a single option-field message to 'usage'. */
  static void getUsageHtml(
      OptionDefinition optionDefinition,
      StringBuilder usage,
      Escaper escaper,
      OptionsData optionsData,
      boolean includeTags) {
    String plainFlagName = optionDefinition.getOptionName();
    String flagName = getFlagName(optionDefinition);
    String valueDescription = optionDefinition.getValueTypeHelpText();
    String typeDescription = getTypeDescription(optionDefinition);

    // String.format is a lot slower, sometimes up to 10x.
    // https://stackoverflow.com/questions/925423/is-it-better-practice-to-use-string-format-over-string-concatenation-in-java
    //
    // Considering that this runs for every flag in the CLI reference, it's better to use regular
    // appends here.
    usage
        // Add the id of the flag to point anchor hrefs to it
        .append("<dt id=\"flag--")
        .append(plainFlagName)
        .append("\">")
        // Add the href to the id hash
        .append("<code><a href=\"#flag--")
        .append(plainFlagName)
        .append("\">")
        .append("--")
        .append(flagName)
        .append("</a>");

    if (!optionDefinition.requiresValue()) {
      // Nothing for boolean, tristate, boolean_or_enum, or void options.
    } else if (!valueDescription.isEmpty()) {
      usage.append("=").append(escaper.escape(valueDescription));
    } else if (!typeDescription.isEmpty()) {
      // Generic fallback, which isn't very good.
      usage.append("=&lt;").append(escaper.escape(typeDescription)).append("&gt");
    }
    usage.append("</code>");
    if (optionDefinition.getAbbreviation() != '\0') {
      usage.append(" [<code>-").append(optionDefinition.getAbbreviation()).append("</code>]");
    }
    if (optionDefinition.allowsMultiple()) {
      // Allow-multiple options can't have a default value.
      usage.append(" multiple uses are accumulated");
    } else {
      // Don't call the annotation directly (we must allow overrides to certain defaults).
      String defaultValueString = optionDefinition.getUnparsedDefaultValue();
      if (optionDefinition.isVoidField()) {
        // Void options don't have a default.
      } else if (optionDefinition.isSpecialNullDefault()) {
        usage.append(" default: see description");
      } else {
        usage.append(" default: \"").append(escaper.escape(defaultValueString)).append("\"");
      }
    }
    usage.append("</dt>\n");
    usage.append("<dd>\n");
    if (!optionDefinition.getHelpText().isEmpty()) {
      usage.append(escaper.escape(optionDefinition.getHelpText()));
      usage.append('\n');
    }

    if (!optionsData.getEvaluatedExpansion(optionDefinition).isEmpty()) {
      // If this is an expansion option, list the expansion if known, or at least specify that we
      // don't know.
      usage.append("<br/>\n");
      ImmutableList<String> expansion = getExpansionIfKnown(optionDefinition, optionsData);
      StringBuilder expandsMsg;
      if (expansion == null) {
        expandsMsg = new StringBuilder("Expands to unknown options.<br/>\n");
      } else {
        Preconditions.checkArgument(!expansion.isEmpty());
        expandsMsg = new StringBuilder("Expands to:<br/>\n");
        for (String exp : expansion) {
          // TODO(jingwen): We link to the expanded flags here, but unfortunately we don't
          // currently guarantee that all flags are only printed once. A flag in an OptionBase that
          // is included by 2 different commands, but not inherited through a parent command, will
          // be printed multiple times. Clicking on the flag will bring the user to its first
          // definition.
          expandsMsg
              .append("&nbsp;&nbsp;")
              .append("<code><a href=\"#flag")
              // Link to the '#flag--flag_name' hash.
              // Some expansions are in the form of '--flag_name=value', so we drop everything from
              // '=' onwards.
              .append(Iterables.get(Splitter.on('=').split(escaper.escape(exp)), 0))
              .append("\">")
              .append(escaper.escape(exp))
              .append("</a></code><br/>\n");
        }
      }
      usage.append(expandsMsg);
    }

    // Add effect tags, if not UNKNOWN, and metadata tags, if not empty.
    if (includeTags) {
      Stream<OptionEffectTag> effectTagStream =
          Arrays.stream(optionDefinition.getOptionEffectTags())
              .filter(OptionsUsage::shouldEffectTagBeListed);
      Stream<OptionMetadataTag> metadataTagStream =
          Arrays.stream(optionDefinition.getOptionMetadataTags())
              .filter(OptionsUsage::shouldMetadataTagBeListed);
      String tagList =
          Stream.concat(
                  effectTagStream.map(
                      tag ->
                          String.format(
                              "<a href=\"#effect_tag_%s\"><code>%s</code></a>",
                              tag, Ascii.toLowerCase(tag.name()))),
                  metadataTagStream.map(
                      tag ->
                          String.format(
                              "<a href=\"#metadata_tag_%s\"><code>%s</code></a>",
                              tag, Ascii.toLowerCase(tag.name()))))
              .collect(Collectors.joining(", "));
      if (!tagList.isEmpty()) {
        usage.append("<br>Tags:\n").append(tagList);
      }
    }

    usage.append("</dd>\n");
  }

  /**
   * Returns the available completion for the given option field. The completions are the exact
   * command line option (with the prepending '--') that one should pass. It is suitable for
   * completion script to use. If the option expect an argument, the kind of argument is given
   * after the equals. If the kind is a enum, the various enum values are given inside an accolade
   * in a comma separated list. For other special kind, the type is given as a name (e.g.,
   * <code>label</code>, <code>float</ode>, <code>path</code>...). Example outputs of this
   * function are for, respectively, a tristate flag <code>tristate_flag</code>, a enum
   * flag <code>enum_flag</code> which can take <code>value1</code>, <code>value2</code> and
   * <code>value3</code>, a path fragment flag <code>path_flag</code>, a string flag
   * <code>string_flag</code> and a void flag <code>void_flag</code>:
   * <pre>
   *   --tristate_flag={auto,yes,no}
   *   --notristate_flag
   *   --enum_flag={value1,value2,value3}
   *   --path_flag=path
   *   --string_flag=
   *   --void_flag
   * </pre>
   *
   * @param optionDefinition The field to return completion for
   * @param builder the string builder to store the completion values
   */
  static void getCompletion(OptionDefinition optionDefinition, StringBuilder builder) {
    // Return the list of possible completions for this option
    String flagName = optionDefinition.getOptionName();
    Class<?> fieldType = optionDefinition.getType();
    builder.append("--").append(flagName);
    if (fieldType.equals(boolean.class)) {
      builder.append("\n");
      builder.append("--no").append(flagName).append("\n");
    } else if (fieldType.equals(TriState.class)) {
      builder.append("={auto,yes,no}\n");
      builder.append("--no").append(flagName).append("\n");
    } else if (fieldType.isEnum()) {
      builder
          .append("={")
          .append(COMMA_JOINER.join(fieldType.getEnumConstants()).toLowerCase(Locale.ENGLISH))
          .append("}\n");
    } else if (fieldType.getSimpleName().equals("Label")) {
      // String comparison so we don't introduce a dependency to com.google.devtools.build.lib.
      builder.append("=label\n");
    } else if (fieldType.getSimpleName().equals("PathFragment")) {
      builder.append("=path\n");
    } else if (Void.class.isAssignableFrom(fieldType)) {
      builder.append("\n");
    } else {
      // TODO(bazel-team): add more types. Maybe even move the completion type
      // to the @Option annotation?
      builder.append("=\n");
    }
  }

  private static String getTypeDescription(OptionDefinition optionsDefinition) {
    return optionsDefinition.getConverter().getTypeDescription();
  }

  static String getFlagName(OptionDefinition optionDefinition) {
    String name = optionDefinition.getOptionName();
    return optionDefinition.usesBooleanValueSyntax() ? "[no]" + name : name;
  }
}
