// 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.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.io.AnsiTerminal;
import com.google.devtools.build.lib.util.io.AnsiTerminalWriter;
import com.google.devtools.build.lib.util.io.LineCountingAnsiTerminalWriter;
import com.google.devtools.build.lib.util.io.LineWrappingAnsiTerminalWriter;
import com.google.devtools.build.lib.util.io.OutErr;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.util.Calendar;
import java.util.Iterator;
import java.util.concurrent.ThreadLocalRandom;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * An event handler for ANSI terminals which uses control characters to
 * provide eye-candy, reduce scrolling, and generally improve usability
 * for users running directly from the shell.
 *
 * <p/>
 * This event handler differs from a normal terminal because it only adds
 * control characters to stderr, not stdout.  All blaze status feedback
 * is sent to stderr, so adding control characters just to that stream gives
 * the benefits described above without modifying the normal output stream.
 * For commands like build that don't generate stdout output this doesn't
 * matter, but for commands like query and ide_build_info, inserting these
 * control characters in stdout invalidated their output.
 *
 * <p/>
 * The underlying streams may be either line-bufferred or unbuffered.
 * Normally each event will write out a sequence of output to a single
 * stream, and will end with a newline, which ensures a flush.
 * But care is required when outputting incomplete lines, or when mixing
 * output between the two different streams (stdout and stderr):
 * it may be necessary to explicitly flush the output in those cases.
 * However, we also don't want to flush too often; that can lead to
 * a choppy UI experience.
 */
public class FancyTerminalEventHandler extends BlazeCommandEventHandler {
  private static final Logger logger = Logger.getLogger(FancyTerminalEventHandler.class.getName());
  private static final Pattern progressPattern = Pattern.compile(
      // Match strings that look like they start with progress info:
      //   [42%] Compiling base/base.cc
      //   [1,442 / 23,476] Compiling base/base.cc
      "^\\[(?:(?:\\d\\d?\\d?%)|(?:[\\d+,]+ / [\\d,]+))\\] ");
  private static final Splitter LINEBREAK_SPLITTER = Splitter.on('\n');
  private static final ImmutableList<String> SPECIAL_MESSAGES =
      ImmutableList.of(
          "Reading startup options from "
              + "HKEY_LOCAL_MACHINE\\Software\\Google\\Devtools\\CurrentVersion",
          "Contacting ftp://microsoft.com/win3.1/downloadcenter",
          "Downloading MSVCR71.DLL",
          "Installing Windows Update 37 of 118...",
          "Sending request to Azure server",
          "Initializing HAL",
          "Loading NDIS2SUP.VXD",
          "Initializing DRM",
          "Contacting license server",
          "Starting EC2 instances",
          "Starting MS-DOS 6.0",
          "Updating virus database",
          "Linking WIN32.DLL",
          "Linking GGL32.EXE",
          "Starting ActiveX controls",
          "Launching Microsoft Visual Studio 2013",
          "Launching IEXPLORE.EXE",
          "Initializing BASIC v2.1 interpreter",
          "Parsing COM object monikers",
          "Notifying field agents",
          "Negotiating with killer robots",
          "Searching for cellular signal",
          "Waiting for workstation CPU temperature to decrease");

  private static final ImmutableSet<Character> PUNCTUATION_CHARACTERS =
      ImmutableSet.<Character>of(',', '.', ':', '?', '!', ';');

  private final Iterator<String> messageIterator = Iterators.cycle(SPECIAL_MESSAGES);
  private volatile boolean trySpecial;
  private volatile Instant skipUntil = Instant.now();

  private final AnsiTerminal terminal;

  private final boolean useColor;
  private final boolean useCursorControls;
  private final boolean progressInTermTitle;
  public final int terminalWidth;

  private boolean terminalClosed = false;
  private boolean previousLineErasable = false;
  private int numLinesPreviousErasable = 0;

  public FancyTerminalEventHandler(
      OutErr outErr, BlazeCommandEventHandler.Options options, PathFragment workspacePathFragment) {
    super(outErr, options, workspacePathFragment);
    this.terminal = new AnsiTerminal(outErr.getErrorStream());
    this.terminalWidth = (options.terminalColumns > 0 ? options.terminalColumns : 80);
    useColor = options.useColor();
    useCursorControls = options.useCursorControl();
    progressInTermTitle = options.progressInTermTitle;
    
    Calendar today = Calendar.getInstance();
    trySpecial = options.forceExternalRepositories 
        || (options.externalRepositories
            && today.get(Calendar.MONTH) == Calendar.APRIL
            && today.get(Calendar.DAY_OF_MONTH) == 1);
  }

  @Override
  public synchronized void handle(Event event) {
    if (terminalClosed) {
      return;
    }
    if (!eventMask.contains(event.getKind())) {
      handleFollowUpEvents(event);
      return;
    }
    if (trySpecial
        && !EventKind.ERRORS_AND_WARNINGS_AND_OUTPUT.contains(event.getKind())
        && skipUntil.isAfter(Instant.now())) {
      // Short-circuit here to avoid wiping out previous terminal contents.
      handleFollowUpEvents(event);
      return;
    }

    try {
      boolean previousLineErased = false;
      if (previousLineErasable) {
        previousLineErased = maybeOverwritePreviousMessage();
      }
      switch (event.getKind()) {
        case PROGRESS:
        case START:
          {
            String message = event.getMessage();
            Pair<String, String> progressPair = matchProgress(message);
            if (progressPair != null) {
              progress(progressPair.getFirst(), progressPair.getSecond());
              if (trySpecial && ThreadLocalRandom.current().nextInt(0, 20) == 0) {
                message = getExtraMessage();
                if (message != null) {
                  // Should always be true, but don't crash on that!
                  previousLineErased = maybeOverwritePreviousMessage();
                  progress(progressPair.getFirst(), message);
                  // Skip unimportant messages for a bit so that this message gets some exposure.
                  skipUntil =
                      Instant.now()
                          .plus(Duration.ofMillis(ThreadLocalRandom.current().nextInt(3000, 8000)));
                }
              }
            } else {
              progress("INFO: ", message);
            }
            break;
          }
        case FINISH:
          {
            String message = event.getMessage();
            Pair<String,String> progressPair = matchProgress(message);
            if (progressPair != null) {
              String percentage = progressPair.getFirst();
              String rest = progressPair.getSecond();
              progress(percentage, rest + " DONE");
            } else {
              progress("INFO: ", message + " DONE");
            }
            break;
          }
        case PASS:
          progress("PASS: ", event.getMessage());
          break;
        case INFO:
          info(event);
          break;
        case ERROR:
        case FAIL:
        case TIMEOUT:
          // For errors, scroll the message, so it appears above the status
          // line, and highlight the word "ERROR" or "FAIL" in boldface red.
          errorOrFail(event);
          break;
        case WARNING:
          // For warnings, highlight the word "Warning" in boldface magenta,
          // and scroll it.
          warning(event);
          break;
        case DEBUG:
          // For debug messages, highlight the word "Debug" in boldface yellow,
          // and scroll it.
          debug(event);
          break;
        case SUBCOMMAND:
          subcmd(event);
          break;
        case STDOUT:
          if (previousLineErased) {
            terminal.flush();
          }
          previousLineErasable = false;
          super.handle(event);
          // We don't need to flush stdout here, because
          // super.handle(event) will take care of that.
          break;
        case STDERR:
          putOutput(event);
          break;
        default:
          // Ignore all other event types.
          break;
      }
    } catch (IOException e) {
      // The terminal shouldn't have IO errors, unless the shell is killed, which
      // should also kill the blaze client. So this isn't something that should
      // occur here; it will show up in the client/server interface as a broken
      // pipe.
      logger.warning("Terminal was closed during build: " + e);
      terminalClosed = true;
    }
    handleFollowUpEvents(event);
  }

  private void handleFollowUpEvents(Event event) {
    if (event.getStdErr() != null) {
      handle(
          Event.of(
              EventKind.STDERR, null, event.getStdErr().getBytes(StandardCharsets.ISO_8859_1)));
    }
    if (event.getStdOut() != null) {
      handle(
          Event.of(
              EventKind.STDOUT, null, event.getStdOut().getBytes(StandardCharsets.ISO_8859_1)));
    }
  }

  private String getExtraMessage() {
    synchronized (messageIterator) {
      if (messageIterator.hasNext()) {
        return messageIterator.next();
      }
    }
    trySpecial = false;
    return null;
  }

  /**
   * Displays a progress message that may be erased by subsequent messages.
   *
   * @param  prefix   a short string such as "[99%] " or "INFO: ", which will be highlighted
   * @param  rest     the remainder of the message; may be multiple lines
   */
  private void progress(String prefix, String rest) throws IOException {
    previousLineErasable = true;

    if (progressInTermTitle) {
      int newlinePos = rest.indexOf('\n');
      if (newlinePos == -1) {
        terminal.setTitle(prefix + rest);
      } else {
        terminal.setTitle(prefix + rest.substring(0, newlinePos));
      }
    }

    LineCountingAnsiTerminalWriter countingWriter = new LineCountingAnsiTerminalWriter(terminal);
    AnsiTerminalWriter terminalWriter = countingWriter;

    if (useCursorControls) {
      terminalWriter = new LineWrappingAnsiTerminalWriter(terminalWriter, terminalWidth - 1);
    }

    if (useColor) {
      terminalWriter.okStatus();
    }
    terminalWriter.append(prefix);
    terminalWriter.normal();
    if (showTimestamp) {
      String timestamp = timestamp();
      terminalWriter.append(timestamp);
    }
    Iterator<String> lines = LINEBREAK_SPLITTER.split(rest).iterator();
    String firstLine = lines.next();
    terminalWriter.append(firstLine);
    terminalWriter.newline();
    while (lines.hasNext()) {
      String line = lines.next();
      terminalWriter.append(line);
      terminalWriter.newline();
    }
    numLinesPreviousErasable = countingWriter.getWrittenLines();
  }

  /**
   * Try to match a message against the "progress message" pattern. If it
   * matches, return the progress percentage, and the rest of the message.
   * @param message the message to match
   * @return a pair containing the progress percentage, and the rest of the
   *    progress message, or null if the message isn't a progress message.
   */
  private Pair<String,String> matchProgress(String message) {
    Matcher m = progressPattern.matcher(message);
    if (m.find()) {
      return Pair.of(message.substring(0, m.end()), message.substring(m.end()));
    } else {
      return null;
    }
  }

  /**
   * Send the terminal controls that will put the cursor on the beginning
   * of the same line if cursor control is on, or the next line if not.
   * @return True if it did any output; if so, caller is responsible for
   *          flushing the terminal if needed.
   */
  private boolean maybeOverwritePreviousMessage() throws IOException {
    if (useCursorControls && numLinesPreviousErasable != 0) {
      for (int i = 0; i < numLinesPreviousErasable; i++) {
        terminal.cr();
        terminal.cursorUp(1);
        terminal.clearLine();
      }
      return true;
    } else {
      return false;
    }
  }

  private void errorOrFail(Event event) throws IOException {
    previousLineErasable = false;
    if (useColor) {
      terminal.textRed();
      terminal.textBold();
    }
    terminal.writeString(event.getKind() + ": ");
    if (useColor) {
      terminal.resetTerminal();
    }
    writeTimestampAndLocation(event);
    writeStringWithPotentialPeriod(event.getMessage());
    crlf();
  }

  private void warning(Event warning) throws IOException {
    previousLineErasable = false;
    if (useColor) {
      terminal.textMagenta();
    }
    terminal.writeString("WARNING: ");
    terminal.resetTerminal();
    writeTimestampAndLocation(warning);
    writeStringWithPotentialPeriod(warning.getMessage());
    crlf();
  }

  private void info(Event event) throws IOException {
    previousLineErasable = false;
    if (useColor) {
      terminal.textGreen();
    }
    terminal.writeString(event.getKind() + ": ");
    terminal.resetTerminal();
    writeTimestampAndLocation(event);
    terminal.writeString(event.getMessage());
    // No period; info messages may end with a URL.
    crlf();
  }

  private void debug(Event debug) throws IOException {
    previousLineErasable = false;
    if (useColor) {
      terminal.textYellow();
    }
    terminal.writeString("DEBUG: ");
    terminal.resetTerminal();
    writeTimestampAndLocation(debug);
    writeStringWithPotentialPeriod(debug.getMessage());
    crlf();
  }

  /**
   * Writes the given String to the terminal. This method also writes a trailing period if the
   * message doesn't end with a punctuation character.
   */
  private void writeStringWithPotentialPeriod(String message) throws IOException {
    terminal.writeString(message);
    if (!message.isEmpty()) {
      char lastChar = message.charAt(message.length() - 1);
      if (!PUNCTUATION_CHARACTERS.contains(lastChar)) {
        terminal.writeString(".");
      }
    }
  }

  private void subcmd(Event subcmd) throws IOException {
    previousLineErasable = false;
    if (useColor) {
      terminal.textBlue();
    }
    terminal.writeString(">>>>> ");
    terminal.resetTerminal();
    writeTimestampAndLocation(subcmd);
    terminal.writeString(subcmd.getMessage());
    crlf();
  }

  /* Handle STDERR events. */
  private void putOutput(Event event) throws IOException {
    previousLineErasable = false;
    terminal.writeBytes(event.getMessageBytes());
/*
 * The following code doesn't work because buildtool.TerminalTestNotifier
 * writes ANSI-formatted text via this mechanism, one character at a time,
 * and if we try to insert additional ANSI sequences in between the characters
 * of another ANSI escape sequence, we screw things up. (?)
 * TODO(bazel-team): (2009) fix this.  TerminalTestNotifier should go via the Reporter
 * rather than via an AnsiTerminalWriter.
 */
//    terminal.resetTerminal();
//    writeTimestampAndLocation(event);
//    if (useColor) {
//      terminal.textNormal();
//    }
//    terminal.writeBytes(event.getMessageBytes());
//    terminal.resetTerminal();
  }

  /**
   * Add a carriage return, shifting to the next line on the terminal, while
   * guaranteeing that the terminal control codes don't cause any strange
   * effects.  Without the CR before the "\n", the "\n" can cause a line-break
   * moving text to the next line, where the new message will be generated.
   * Emitting a "CR" before means that the actual terminal controls generated
   * here are CR+CR+LF; the double-CR resets the terminal line state, which
   * prevents the potentially ugly formatting issue.
   */
  private void crlf() throws IOException {
    terminal.cr();
    terminal.writeString("\n");
  }

  private void writeTimestampAndLocation(Event event) throws IOException {
    if (showTimestamp) {
      terminal.writeString(timestamp());
    }
    if (event.getLocation() != null) {
      terminal.writeString(locationPrinter.getLocationString(event.getLocation()) + ": ");
    }
  }

  public void resetTerminal() {
    try {
      terminal.resetTerminal();
    } catch (IOException e) {
      logger.warning("IO Error writing to user terminal: " + e);
    }
  }
}
