// Copyright 2022 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.bazel.bzlmod.modcommand;

import static java.util.Arrays.stream;
import static java.util.stream.Collectors.joining;

import com.google.common.base.Ascii;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.bazel.bzlmod.ModuleKey;
import com.google.devtools.build.lib.bazel.bzlmod.modcommand.ExtensionArg.CommaSeparatedExtensionArgListConverter;
import com.google.devtools.build.lib.bazel.bzlmod.modcommand.ModuleArg.CommaSeparatedModuleArgListConverter;
import com.google.devtools.build.lib.bazel.bzlmod.modcommand.ModuleArg.ModuleArgConverter;
import com.google.devtools.common.options.EnumConverter;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.devtools.common.options.OptionsBase;

/** Options for ModCommand */
public class ModOptions extends OptionsBase {

  @Option(
      name = "from",
      defaultValue = "<root>",
      converter = CommaSeparatedModuleArgListConverter.class,
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "The module(s) starting from which the dependency graph query will be displayed. Check"
              + " each query’s description for the exact semantics. Defaults to <root>.\n")
  public ImmutableList<ModuleArg> modulesFrom;

  @Option(
      name = "verbose",
      defaultValue = "false",
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "The queries will also display the reason why modules were resolved to their current"
              + " version (if changed). Defaults to true only for the explain query.")
  public boolean verbose;

  @Option(
      name = "include_unused",
      defaultValue = "false",
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "The queries will also take into account and display the unused modules, which are not"
              + " present in the module resolution graph after selection (due to the"
              + " Minimal-Version Selection or override rules). This can have different effects for"
              + " each of the query types i.e. include new paths in the all_paths command, or extra"
              + " dependants in the explain command.")
  public boolean includeUnused;

  @Option(
      name = "extension_filter",
      defaultValue = "null",
      converter = CommaSeparatedExtensionArgListConverter.class,
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "Only display the usages of these module extensions and the repos generated by them if"
              + " their respective flags are set. If set, the result graph will only include paths"
              + " that contain modules using the specified extensions. An empty list disables the"
              + " filter, effectively specifying all possible extensions.")
  public ImmutableList<ExtensionArg> extensionFilter;

  @Option(
      name = "extension_info",
      defaultValue = "hidden",
      converter = ExtensionShowConverter.class,
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "Specify how much detail about extension usages to include in the query result."
              + " \"Usages\" will only show the extensions names, \"repos\" will also include repos"
              + " imported with use_repo, and \"all\" will also show the other repositories"
              + " generated by extensions.\n")
  public ExtensionShow extensionInfo;

  @Option(
      name = "base_module",
      defaultValue = "<root>",
      converter = ModuleArgConverter.class,
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help = "Specify a module relative to which the specified target repos will be interpreted.")
  public ModuleArg baseModule;

  @Option(
      name = "extension_usages",
      defaultValue = "",
      converter = CommaSeparatedModuleArgListConverter.class,
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "Specify modules whose extension usages will be displayed in the show_extension query.")
  public ImmutableList<ModuleArg> extensionUsages;

  @Option(
      name = "depth",
      defaultValue = "-1",
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "Maximum display depth of the dependency tree. A depth of 1 displays the direct"
              + " dependencies, for example. For tree, path and all_paths it defaults to"
              + " Integer.MAX_VALUE, while for deps and explain it defaults to 1 (only displays"
              + " direct deps of the root besides the target leaves and their parents).\n")
  public int depth;

  @Option(
      name = "cycles",
      defaultValue = "false",
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "Points out dependency cycles inside the displayed tree, which are normally ignored by"
              + " default.")
  public boolean cycles;

  @Option(
      name = "include_builtin",
      defaultValue = "false",
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "Include built-in modules in the dependency graph. Disabled by default because it is"
              + " quite noisy.")
  public boolean includeBuiltin;

  @Option(
      name = "charset",
      defaultValue = "utf8",
      converter = CharsetConverter.class,
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "Chooses the character set to use for the tree. Only affects text output. Valid values"
              + " are \"utf8\" or \"ascii\". Default is \"utf8\"")
  public Charset charset;

  @Option(
      name = "output",
      defaultValue = "text",
      converter = OutputFormatConverter.class,
      documentationCategory = OptionDocumentationCategory.MOD_COMMAND,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "The format in which the query results should be printed. Allowed values for query are: "
              + "text, json, graph")
  public OutputFormat outputFormat;

  /** Possible subcommands that can be specified for the `mod` command. */
  public enum ModSubcommand {
    DEPS(true),
    GRAPH(true),
    ALL_PATHS(true),
    PATH(true),
    EXPLAIN(true),
    SHOW_REPO(false),
    SHOW_EXTENSION(false);

    /** Whether this subcommand produces a graph output. */
    private final boolean isGraph;

    ModSubcommand(boolean isGraph) {
      this.isGraph = isGraph;
    }

    @Override
    public String toString() {
      return Ascii.toLowerCase(this.name());
    }

    public boolean isGraph() {
      return isGraph;
    }

    public static String printValues() {
      return "(" + stream(values()).map(ModSubcommand::toString).collect(joining(", ")) + ")";
    }
  }

  /** Converts a subcommand string to a properly typed {@link ModSubcommand} */
  public static class ModSubcommandConverter extends EnumConverter<ModSubcommand> {
    public ModSubcommandConverter() {
      super(ModSubcommand.class, "mod subcommand");
    }
  }

  enum ExtensionShow {
    HIDDEN,
    USAGES,
    REPOS,
    ALL
  }

  /** Converts an option string to a properly typed {@link ExtensionShow} */
  public static class ExtensionShowConverter extends EnumConverter<ExtensionShow> {
    public ExtensionShowConverter() {
      super(ExtensionShow.class, "extension show");
    }
  }

  /** Charset to be used in outputting the `mod` command result. */
  public enum Charset {
    UTF8,
    ASCII
  }

  /** Converts a charset option string to a properly typed {@link Charset} */
  public static class CharsetConverter extends EnumConverter<Charset> {
    public CharsetConverter() {
      super(Charset.class, "output charset");
    }
  }

  /** Possible formats of the `mod` command result. */
  public enum OutputFormat {
    TEXT,
    JSON,
    GRAPH
  }

  /** Converts an output format option string to a properly typed {@link OutputFormat} */
  public static class OutputFormatConverter extends EnumConverter<OutputFormat> {
    public OutputFormatConverter() {
      super(OutputFormat.class, "output format");
    }
  }

  /** Returns a {@link ModOptions} filled with default values for testing. */
  static ModOptions getDefaultOptions() {
    ModOptions options = new ModOptions();
    options.depth = Integer.MAX_VALUE;
    options.cycles = false;
    options.includeUnused = false;
    options.verbose = false;
    options.modulesFrom =
        ImmutableList.of(ModuleArg.SpecificVersionOfModule.create(ModuleKey.ROOT));
    options.charset = Charset.UTF8;
    options.outputFormat = OutputFormat.TEXT;
    options.extensionFilter = null;
    options.extensionInfo = ExtensionShow.HIDDEN;
    return options;
  }
}
