// 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.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.util.io.OutErr;
import com.google.devtools.common.options.EnumConverter;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;

import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.EnumSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * BlazeCommandEventHandler: an event handler established for the duration of a
 * single Blaze command.
 */
public class BlazeCommandEventHandler implements EventHandler {

  private static final Logger LOG = Logger.getLogger(BlazeCommandEventHandler.class.getName());

  public enum UseColor { YES, NO, AUTO }
  public enum UseCurses { YES, NO, AUTO }

  public static class UseColorConverter extends EnumConverter<UseColor> {
    public UseColorConverter() {
      super(UseColor.class, "--color setting");
    }
  }

  public static class UseCursesConverter extends EnumConverter<UseCurses> {
    public UseCursesConverter() {
      super(UseCurses.class, "--curses setting");
    }
  }

  public static class Options extends OptionsBase {

    @Option(name = "show_progress",
            defaultValue = "true",
            category = "verbosity",
            help = "Display progress messages during a build.")
    public boolean showProgress;

    @Option(name = "show_task_finish",
            defaultValue = "false",
            category = "verbosity",
            help = "Display progress messages when tasks complete, not just when they start.")
    public boolean showTaskFinish;

    @Option(name = "show_progress_rate_limit",
            defaultValue = "0.03",  // A nice middle ground; snappy but not too spammy in logs.
            category = "verbosity",
            help = "Minimum number of seconds between progress messages in the output.")
    public double showProgressRateLimit;

    @Option(name = "color",
            defaultValue = "auto",
            converter = UseColorConverter.class,
            category = "verbosity",
            help = "Use terminal controls to colorize output.")
    public UseColor useColorEnum;

    @Option(name = "curses",
            defaultValue = "auto",
            converter = UseCursesConverter.class,
            category = "verbosity",
            help = "Use terminal cursor controls to minimize scrolling output")
    public UseCurses useCursesEnum;

    @Option(name = "terminal_columns",
            defaultValue = "80",
            category = "hidden",
            help = "A system-generated parameter which specifies the terminal "
               + " width in columns.")
    public int terminalColumns;

    @Option(name = "isatty",
            defaultValue = "false",
            category = "hidden",
            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",
            category = "undocumented",
            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",
        category = "verbosity",
        help = "Include timestamps in messages")
    public boolean showTimestamp;

    @Option(name = "progress_in_terminal_title",
        defaultValue = "false",
        category = "verbosity",
        help = "Show the command progress in the terminal title. "
            + "Useful to see what blaze is doing when having multiple terminal tabs.")
    public boolean progressInTermTitle;

    @Option(name = "experimental_external_repositories",
        defaultValue = "false",
        category = "verbosity",
        help = "Use external repositories for improved stability and speed when available.")
    public boolean externalRepositories;

    @Option(name = "force_experimental_external_repositories",
        defaultValue = "false",
        category = "verbosity",
        help = "Forces --experimental_external_repositories.")
    public boolean forceExternalRepositories;

    @Option(
      name = "experimental_ui",
      defaultValue = "false",
      category = "verbosity",
      help = "Switches to an alternative progress bar that more explicitly shows progress, such "
          + "as loaded packages and executed actions.")
    public boolean experimentalUi;

    @Option(
      name = "experimental_ui_debug_all_events",
      defaultValue = "false",
      category = "hidden",
      help = "Report all events known to the experimental new Bazel UI."
    )
    public boolean experimentalUiDebugAllEvents;

    @Option(
      name = "experimental_ui_actions_shown",
      defaultValue = "3",
      category = "verbosity",
      help =
          "Number of concurrent actions shown in the alternative progress bar; each "
              + "action is shown on a separate line. The alternative progress bar always shows "
              + "at least one one, all numbers less than 1 are mapped to 1. "
              + "This option has no effect unless --experimental_ui is set."
    )
    public int experimentalUiActionsShown;

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

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

  private static final DateTimeFormatter TIMESTAMP_FORMAT =
      DateTimeFormat.forPattern("(MM-dd HH:mm:ss.SSS) ");

  protected final OutErr outErr;

  private final PrintStream errPrintStream;

  protected final Set<EventKind> eventMask =
      EnumSet.copyOf(EventKind.ERRORS_WARNINGS_AND_INFO_AND_OUTPUT);

  protected final boolean showTimestamp;

  public BlazeCommandEventHandler(OutErr outErr, Options eventOptions) {
    this.outErr = outErr;
    this.errPrintStream = new PrintStream(outErr.getErrorStream(), true);
    if (eventOptions.showProgress) {
      eventMask.add(EventKind.PROGRESS);
      eventMask.add(EventKind.START);
    } else {
      // Skip PASS events if --noshow_progress is requested.
      eventMask.remove(EventKind.PASS);
    }
    if (eventOptions.showTaskFinish) {
      eventMask.add(EventKind.FINISH);
    }
    eventMask.add(EventKind.SUBCOMMAND);
    this.showTimestamp = eventOptions.showTimestamp;
  }

  /** See EventHandler.handle. */
  @Override
  public void handle(Event event) {
    if (!eventMask.contains(event.getKind())) {
      return;
    }
    String prefix;
    switch (event.getKind()) {
      case STDOUT:
        putOutput(outErr.getOutputStream(), event);
        return;
      case STDERR:
        putOutput(outErr.getErrorStream(), event);
        return;
      case PASS:
      case FAIL:
      case TIMEOUT:
      case ERROR:
      case WARNING:
      case DEPCHECKER:
        prefix = event.getKind() + ": ";
        break;
      case SUBCOMMAND:
        prefix = ">>>>>>>>> ";
        break;
      case INFO:
      case PROGRESS:
      case START:
      case FINISH:
        prefix = "____";
        break;
      default:
        throw new IllegalStateException("" + event.getKind());
    }
    StringBuilder buf = new StringBuilder();
    buf.append(prefix);

    if (showTimestamp) {
      buf.append(timestamp());
    }

    Location location = event.getLocation();
    if (location != null) {
      buf.append(location.print()).append(": ");
    }

    buf.append(event.getMessage());
    if (event.getKind() == EventKind.FINISH) {
      buf.append(" DONE");
    }

    // Add a trailing period for ERROR and WARNING messages, which are
    // typically English sentences composed from exception messages.
    if (event.getKind() == EventKind.WARNING ||
        event.getKind() == EventKind.ERROR) {
      buf.append('.');
    }

    // Event messages go to stderr; results (e.g. 'blaze query') go to stdout.
    errPrintStream.println(buf);
  }

  private void putOutput(OutputStream out, Event event) {
    try {
      out.write(event.getMessageBytes());
      out.flush();
    } catch (IOException e) {
      // This can happen in server mode if the blaze client has exited, or if output is redirected
      // to a file and the disk is full, etc. May be moot in the case of full disk, or useful in
      // the case of real bug in our handling of streams.
      LOG.log(Level.WARNING, "Failed to write event", e);
    }
  }

  /**
   * @return a string representing the current time, eg "04-26 13:47:32.124".
   */
  protected String timestamp() {
    return TIMESTAMP_FORMAT.print(System.currentTimeMillis());
  }
}
