// 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.common.base.Preconditions;
import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;

/**
 * A pair of output streams to be used for redirecting the output and error streams of a subprocess.
 */
public class OutErr implements Closeable {

  private final OutputStream out;
  private final OutputStream err;

  public static final OutErr SYSTEM_OUT_ERR = create(System.out, System.err);

  /**
   * Creates a new OutErr instance from the specified output and error streams.
   */
  public static OutErr create(OutputStream out, OutputStream err) {
    return new OutErr(out, err);
  }

  protected OutErr(OutputStream out, OutputStream err) {
    this.out = Preconditions.checkNotNull(out);
    this.err = Preconditions.checkNotNull(err);
  }

  @Override
  public void close() throws IOException {
    // Ensure that we close both out and err even if one throws.
    try {
      out.close();
    } finally {
      if (out != err) {
        err.close();
      }
    }
  }

  /**
   * Temporarily patches {@link System#out} and {@link System#err} with custom streams.
   *
   * <p>{@link #start} is called to signal the beginning of the scope of the patch. {@link #close}
   * ends the scope of the patch, returning {@link System#out} and {@link System#err} to what they
   * were before.
   */
  public interface SystemPatcher extends AutoCloseable {
    void start();
  }

  /** Returns a {@link SystemPatcher} that uses this instance's out and err streams. */
  public final SystemPatcher getSystemPatcher() {
    PrintStream savedOut = System.out;
    PrintStream savedErr = System.err;
    SwitchingPrintStream outPatch = new SwitchingPrintStream(out);
    SwitchingPrintStream errPatch = new SwitchingPrintStream(err);
    return new SystemPatcher() {
      @Override
      public void start() {
        System.setOut(outPatch);
        System.setErr(errPatch);
      }

      @Override
      public void close() {
        System.setOut(savedOut);
        System.setErr(savedErr);
        outPatch.switchBackTo(savedOut);
        errPatch.switchBackTo(savedErr);
      }
    };
  }

  /**
   * Starts by streaming to {@code override}, then switches back to {@code saved}.
   *
   * <p>The switching strategy is used to guard against memory leaks. For example, if {@code
   * override} is passed directly to {@link System#setErr}, anyone may retain a reference to it via
   * {@link System#err}. Instead, they will get a reference to this class, which frees up {@code
   * override} in {@link #switchBackTo}.
   */
  private static final class SwitchingPrintStream extends PrintStream {

    private SwitchingPrintStream(OutputStream override) {
      super(override, /*autoFlush=*/ true);
    }

    private void switchBackTo(OutputStream saved) {
      out = saved;
    }
  }

  /**
   * Creates a new OutErr instance from the specified stream.
   * Writes to either the output or err of the new OutErr are written
   * to outputStream, synchronized.
   */
  public static OutErr createSynchronizedFunnel(final OutputStream outputStream) {
    OutputStream syncOut = new OutputStream() {

      @Override
      public synchronized void write(int b) throws IOException {
        outputStream.write(b);
      }

      @Override
      public synchronized void write(byte b[]) throws IOException {
        outputStream.write(b);
      }

      @Override
      public synchronized  void write(byte b[], int off, int len) throws IOException {
        outputStream.write(b, off, len);
      }

      @Override
      public synchronized void flush() throws IOException {
        outputStream.flush();
      }

      @Override
      public synchronized void close() throws IOException {
        outputStream.close();
      }
    };

    return create(syncOut, syncOut);
  }

  public OutputStream getOutputStream() {
    return out;
  }

  public OutputStream getErrorStream() {
    return err;
  }

  /**
   * Writes the specified string to the output stream, and flushes.
   */
  public void printOut(String s) {
    PrintWriter writer = new PrintWriter(out, true);
    writer.print(s);
    writer.flush();
  }

  public void printOutLn(String s) {
    printOut(s + "\n");
  }

  /**
   * Writes the specified string to the error stream, and flushes.
   */
  public void printErr(String s) {
    PrintWriter writer = new PrintWriter(err, true);
    writer.print(s);
    writer.flush();
  }

  public void printErrLn(String s) {
    printErr(s + "\n");
  }

}
