// 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.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * An {@link OutErr} specialization that supports subscribing / removing
 * sinks, using {@link #addSink(OutErr)} and {@link #removeSink(OutErr)}.
 * A sink is a destination to which the {@link DelegatingOutErr} will write.
 *
 * Also, we can hook up {@link System#out} / {@link System#err} as sources.
 */
public final class DelegatingOutErr extends OutErr {

  /**
   * Create a new instance to which no sinks have subscribed (basically just
   * like a {@code /dev/null}.
   */
  public DelegatingOutErr() {
    super(new DelegatingOutputStream(), new DelegatingOutputStream());
  }


  private final DelegatingOutputStream outSink() {
    return (DelegatingOutputStream) getOutputStream();
  }

  private final DelegatingOutputStream errSink() {
    return (DelegatingOutputStream) getErrorStream();
  }

  /**
   * Add a sink, that is, after calling this method, {@code outErrSink} will
   * receive all output / errors written to {@code this} object.
   */
  public void addSink(OutErr outErrSink) {
    outSink().addSink(outErrSink.getOutputStream());
    errSink().addSink(outErrSink.getErrorStream());
  }

  /**
   * Remove the sink, that is, after calling this method, {@code outErrSink}
   * will no longer receive output / errors written to {@code this} object.
   */
  public void removeSink(OutErr outErrSink) {
    outSink().removeSink(outErrSink.getOutputStream());
    errSink().removeSink(outErrSink.getErrorStream());
  }

  private static class DelegatingOutputStream extends OutputStream {

    private final List<OutputStream> sinks = new ArrayList<>();

    public void addSink(OutputStream sink) {
      sinks.add(Preconditions.checkNotNull(sink));
    }

    public void removeSink(OutputStream sink) {
      sinks.remove(sink);
    }

    @Override
    public void write(int b) throws IOException {
      for (OutputStream sink : sinks) {
        sink.write(b);
      }
    }

    @Override
    public void close() throws IOException {
      for (OutputStream sink : sinks) {
        sink.close();
      }
    }

    @Override
    public void flush() throws IOException {
      for (OutputStream sink : sinks) {
        sink.flush();
      }
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
      for (OutputStream sink : sinks) {
        sink.write(b, off, len);
      }
    }

    @Override
    public void write(byte[] b) throws IOException {
      for (OutputStream sink : sinks) {
        sink.write(b);
      }
    }
  }
}
