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

import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.common.options.Converter;
import com.google.devtools.common.options.Converters.CommaSeparatedOptionListConverter;
import com.google.devtools.common.options.Converters.RangeConverter;
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.OptionMetadataTag;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParsingException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/** Command-line UI options. */
public class UiOptions extends OptionsBase {

  /** Enum to select whether color output is enabled or not. */
  public enum UseColor {
    YES,
    NO,
    AUTO
  }

  /** Enum to select whether curses output is enabled or not. */
  public enum UseCurses {
    YES,
    NO,
    AUTO
  }

  /** Converter for {@link EventKind} filters * */
  public static class EventFiltersConverter implements Converter<List<EventKind>> {

    /** A converter for event kinds. */
    public static class EventKindConverter extends EnumConverter<EventKind> {

      public EventKindConverter(String typeName) {
        super(EventKind.class, typeName);
      }
    }

    private final CommaSeparatedOptionListConverter delegate;

    public EventFiltersConverter() {
      this.delegate = new CommaSeparatedOptionListConverter();
    }

    @Override
    public List<EventKind> convert(String input) throws OptionsParsingException {
      if (input.isEmpty()) {
        // This method is not called to convert the default value
        // Empty list means that the user wants to filter all events
        return new ArrayList<>(EventKind.ALL_EVENTS);
      }
      List<String> filters = this.delegate.convert(input);
      EnumConverter<EventKind> eventKindConverter = new EventKindConverter(input);

      HashSet<EventKind> filteredEvents = new HashSet<>();
      for (String filter : filters) {
        if (!filter.startsWith("+") && !filter.startsWith("-")) {
          filteredEvents.addAll(EventKind.ALL_EVENTS);
          break;
        }
      }

      for (String filter : filters) {
        if (filter.startsWith("+")) {
          filteredEvents.remove(eventKindConverter.convert(filter.substring(1)));
        } else if (filter.startsWith("-")) {
          filteredEvents.add(eventKindConverter.convert(filter.substring(1)));
        } else {
          filteredEvents.remove(eventKindConverter.convert(filter));
        }
      }
      return new ArrayList<>(filteredEvents);
    }

    @Override
    public String getTypeDescription() {
      return "Convert list of comma separated event kind to list of filters";
    }
  }

  /** Converter for {@link UseColor}. */
  public static class UseColorConverter extends EnumConverter<UseColor> {
    public UseColorConverter() {
      super(UseColor.class, "--color setting");
    }
  }

  /** Converter for {@link UseCurses}. */
  public static class UseCursesConverter extends EnumConverter<UseCurses> {
    public UseCursesConverter() {
      super(UseCurses.class, "--curses setting");
    }
  }

  @Option(
      name = "show_progress",
      defaultValue = "true",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Display progress messages during a build.")
  public boolean showProgress;

  @Option(
      name = "show_task_finish",
      defaultValue = "false",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Display progress messages when tasks complete, not just when they start.")
  public boolean showTaskFinish;

  @Option(
      name = "show_progress_rate_limit",
      defaultValue = "0.2", // A nice middle ground; snappy but not too spammy in logs.
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Minimum number of seconds between progress messages in the output.")
  public double showProgressRateLimit;

  @Option(
      name = "color",
      defaultValue = "auto",
      converter = UseColorConverter.class,
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Use terminal controls to colorize output.")
  public UseColor useColorEnum;

  @Option(
      name = "curses",
      defaultValue = "auto",
      converter = UseCursesConverter.class,
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Use terminal cursor controls to minimize scrolling output.")
  public UseCurses useCursesEnum;

  @Option(
      name = "terminal_columns",
      defaultValue = "80",
      metadataTags = {OptionMetadataTag.HIDDEN},
      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "A system-generated parameter which specifies the terminal width in columns.")
  public int terminalColumns;

  @Option(
      name = "isatty",
      defaultValue = "false",
      metadataTags = {OptionMetadataTag.HIDDEN},
      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help =
          "A system-generated parameter which is used to notify the "
              + "server whether this client is running in a terminal. "
              + "If this is set to false, then '--color=auto' will be treated as '--color=no'. "
              + "If this is set to true, then '--color=auto' will be treated as '--color=yes'.")
  public boolean isATty;

  // This lives here (as opposed to the more logical BuildRequest.Options)
  // because the client passes it to the server *always*.  We don't want the
  // client to have to figure out when it should or shouldn't to send it.
  @Option(
      name = "emacs",
      defaultValue = "false",
      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help =
          "A system-generated parameter which is true iff EMACS=t or INSIDE_EMACS is set "
              + "in the environment of the client.  This option controls certain display "
              + "features.")
  public boolean runningInEmacs;

  @Option(
      name = "show_timestamps",
      defaultValue = "false",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Include timestamps in messages")
  public boolean showTimestamp;

  @Option(
      name = "progress_in_terminal_title",
      defaultValue = "false",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help =
          "Show the command progress in the terminal title. "
              + "Useful to see what bazel is doing when having multiple terminal tabs.")
  public boolean progressInTermTitle;

  @Option(
      name = "attempt_to_print_relative_paths",
      oldName = "experimental_ui_attempt_to_print_relative_paths",
      defaultValue = "false",
      documentationCategory = OptionDocumentationCategory.LOGGING,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "When printing the location part of messages, attempt to use a path relative to the "
              + "workspace directory or one of the directories specified by --package_path.")
  public boolean attemptToPrintRelativePaths;

  @Option(
      name = "experimental_ui_debug_all_events",
      defaultValue = "false",
      metadataTags = {OptionMetadataTag.HIDDEN},
      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Report all events known to the Bazel UI.")
  public boolean experimentalUiDebugAllEvents;

  @Option(
      name = "ui_event_filters",
      converter = EventFiltersConverter.class,
      defaultValue = "null",
      documentationCategory = OptionDocumentationCategory.LOGGING,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "Specifies which events to show in the UI. It is possible to add or remove events "
              + "to the default ones using leading +/-, or override the default "
              + "set completely with direct assignment. The set of supported event kinds "
              + "include INFO, DEBUG, ERROR and more.",
      allowMultiple = true)
  public List<EventKind> eventFilters;

  @Option(
      name = "ui_actions_shown",
      oldName = "experimental_ui_actions_shown",
      defaultValue = "8",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
      help =
          "Number of concurrent actions shown in the detailed progress bar; each "
              + "action is shown on a separate line. The progress bar always shows "
              + "at least one one, all numbers less than 1 are mapped to 1.")
  public int uiActionsShown;

  @Option(
      name = "experimental_ui_max_stdouterr_bytes",
      documentationCategory = OptionDocumentationCategory.EXECUTION_STRATEGY,
      effectTags = {OptionEffectTag.EXECUTION},
      defaultValue = "1048576",
      converter = MaxStdoutErrBytesConverter.class,
      help =
          "The maximum size of the stdout / stderr files that will be printed to the console. "
              + "-1 implies no limit.")
  public int maxStdoutErrBytes;

  public boolean useColor() {
    return useColorEnum == UseColor.YES || (useColorEnum == UseColor.AUTO && isATty);
  }

  public boolean useCursorControl() {
    return useCursesEnum == UseCurses.YES || (useCursesEnum == UseCurses.AUTO && isATty);
  }

  /** A converter for --experimental_ui_max_stdouterr_bytes. */
  public static class MaxStdoutErrBytesConverter extends RangeConverter {

    /**
     * The maximum value of the flag must be limited to ensure conversions to UTF-8 do not trigger
     * integer overflows. In JDK9+, if the message buffer contains a byte whose high bit is set, a
     * UTF-8 decoding path is taken that allocates a new byte[] buffer twice as large as the message
     * byte[] buffer.
     */
    private static final int MAX_VALUE = (Integer.MAX_VALUE - 8) >> 1;

    public MaxStdoutErrBytesConverter() {
      super(-1, (Integer.MAX_VALUE - 8) >> 1);
    }

    @Override
    public Integer convert(String input) throws OptionsParsingException {
      Integer value = super.convert(input);
      return value >= 0 ? value : MAX_VALUE;
    }
  }
}
