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

import com.google.devtools.build.lib.util.io.OutErr;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Set;

/**
 * An event handler that prints to an OutErr stream pair in a
 * canonical format, for example:
 * <pre>
 * ERROR: /home/jrluser/src/workspace/x/BUILD:23:1: syntax error.
 * </pre>
 * This syntax is parseable by Emacs's compile.el.
 */
public class PrintingEventHandler extends AbstractEventHandler
    implements EventHandler {

  /**
   * A convenient event-handler for terminal applications that prints all
   * errors and warnings it encounters to the error stream.
   * STDOUT and STDERR events pass their output directly
   * through to the corresponding streams.
   */
  public static final PrintingEventHandler ERRORS_AND_WARNINGS_TO_STDERR =
      new PrintingEventHandler(EventKind.ERRORS_AND_WARNINGS_AND_OUTPUT);

  /**
   * A convenient event-handler for terminal applications that prints all
   * errors it encounters to the error stream.
   * STDOUT and STDERR events pass their output directly
   * through to the corresponding streams.
   */
  public static final PrintingEventHandler ERRORS_TO_STDERR =
      new PrintingEventHandler(EventKind.ERRORS_AND_OUTPUT);

  private OutErr outErr;

  /**
   * Setup a printing event handler that prints events matching the mask.
   */
  public PrintingEventHandler(OutErr outErr, Set<EventKind> mask) {
    super(mask);
    this.outErr = outErr;
  }

  /**
   * Setup a printing event handler that prints events matching the mask. Events are printed to the
   * System.out and System.err unless/until redirected by a call to setOutErr().
   */
  public PrintingEventHandler(Set<EventKind> mask) {
    this(OutErr.SYSTEM_OUT_ERR, mask);
  }

  /**
   * Redirect all output to the specified OutErr stream pair.
   * Returns the previous OutErr.
   */
  public OutErr setOutErr(OutErr outErr) {
    OutErr prev = this.outErr;
    this.outErr = outErr;
    return prev;
  }

  /**
   * Print a description of the specified event to the appropriate
   * output or error stream.
   */
  @Override
  public void handle(Event event) {
    if (!getEventMask().contains(event.getKind())) {
      handleFollowUpEvents(event);
      return;
    }
    try {
      switch (event.getKind()) {
        case STDOUT:
          outErr.getOutputStream().write(event.getMessageBytes());
          outErr.getOutputStream().flush();
          break;
        case STDERR:
          outErr.getErrorStream().write(event.getMessageBytes());
          outErr.getErrorStream().flush();
          break;
        default:
          StringBuilder builder = new StringBuilder();
          builder.append(event.getKind()).append(": ");
          if (event.getLocation() != null) {
            builder.append(event.getLocation().print()).append(": ");
          }
          builder.append(event.getMessage()).append("\n");
          outErr.getErrorStream().write(builder.toString().getBytes(StandardCharsets.UTF_8));
          outErr.getErrorStream().flush();
      }
    } catch (IOException e) {
      /*
       * Note: we can't print to System.out or System.err here,
       * because those will normally be set to streams which
       * translate I/O to STDOUT and STDERR events,
       * which would result in infinite recursion.
       */
      outErr.printErrLn(e.getMessage());
    }
    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)));
    }
  }

}
