// 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.util.io;

import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.EnumSet;
import java.util.logging.Logger;
import java.util.regex.Pattern;

/**
 * Allows to print "colored" strings by parsing predefined string keywords,
 * which, depending on the useColor value are either replaced with ANSI terminal
 * coloring sequences (as defined by the {@link AnsiTerminal} class) or stripped.
 *
 * Supported keywords are defined by the enum {@link AnsiTerminalPrinter.Mode}.
 * Following keywords are supported:
 *   INFO  - switches color to green.
 *   ERROR - switches color to bold red.
 *   WARNING - switches color to magenta.
 *   NORMAL - resets terminal to the default state.
 *
 * Each keyword is starts with prefix "{#" followed by the enum constant name
 * and suffix "#}". Keywords should not be inserted manually - provided enum
 * constants should be used instead.
 */
@ThreadCompatible
public class AnsiTerminalPrinter {

  private static final String MODE_PREFIX = "{#";
  private static final String MODE_SUFFIX = "#}";

  // Mode pattern must match MODE_PREFIX and do lookahead for the rest of the
  // mode string.
  private static final String MODE_PATTERN = "\\{\\#(?=[A-Z]+\\#\\})";

  /**
   * List of supported coloring modes for the {@link AnsiTerminalPrinter}.
   */
  public static enum Mode {
    INFO,     // green
    ERROR,    // bold red
    WARNING,  // magenta
    DEFAULT;  // default color

    @Override
    public String toString() {
      return MODE_PREFIX + name() + MODE_SUFFIX;
    }
  }

  private static final Logger LOG = Logger.getLogger(AnsiTerminalPrinter.class.getName());
  private static final EnumSet<Mode> MODES = EnumSet.allOf(Mode.class);
  private static final Pattern PATTERN = Pattern.compile(MODE_PATTERN);

  private final OutputStream stream;
  private final PrintWriter writer;
  private final AnsiTerminal terminal;
  private boolean useColor;
  private Mode lastMode = Mode.DEFAULT;

  /**
   * Creates new instance using provided OutputStream and sets coloring logic
   * for that instance.
   */
  public AnsiTerminalPrinter(OutputStream out, boolean useColor) {
    this.useColor = useColor;
    terminal = new AnsiTerminal(out);
    writer = new PrintWriter(out, true);
    stream = out;
  }

  /**
   * Writes the specified string to the output stream while injecting coloring
   * sequences when appropriate mode keyword is found and flushes.
   *
   * List of supported mode keywords is defined by the enum {@link Mode}.
   *
   * See class documentation for details.
   */
  public void print(String str) {
    for (String part : PATTERN.split(str)) {
      int index = part.indexOf(MODE_SUFFIX);
      // Mode name will contain at least one character, so suffix index
      // must be at least 1. If it isn't then there is no match.
      if (index > 1) {
        for (Mode mode : MODES) {
          if (index == mode.name().length() && part.startsWith(mode.name())) {
            setupTerminal(mode);
            part = part.substring(index + MODE_SUFFIX.length());
            break;
          }
        }
      }
      writer.print(part);
      writer.flush();
    }
  }

  public void printLn(String str) {
    print(str + "\n");
  }

  /**
   * Returns the underlying OutputStream.
   */
  public OutputStream getOutputStream() {
    return stream;
  }

  /**
   * Injects coloring escape sequences if output should be colored and mode
   * has been changed.
   */
  private void setupTerminal(Mode mode) {
    if (!useColor) {
      return;
    }
    try {
      if (lastMode != mode) {
        terminal.resetTerminal();
        lastMode = mode;
        if (mode == Mode.DEFAULT) {
          return; // Terminal is already reset - nothing else to do.
        } else if (mode == Mode.INFO) {
          terminal.textGreen();
        } else if (mode == Mode.ERROR) {
          terminal.textRed();
          terminal.textBold();
        } else if (mode == Mode.WARNING) {
          terminal.textMagenta();
        }
      }
    } catch (IOException e) {
      // AnsiTerminal state is now considered to be inconsistent - coloring
      // should be disabled to prevent future use of AnsiTerminal instance.
      LOG.warning("Disabling coloring due to " + e.getMessage());
      useColor = false;
    }
  }
}
