/*
 * Copyright 2016 Google Inc.
 *
 * 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 java.util.stream;

import java.util.ArrayList;
import java.util.List;

// package protected, as not part of jre
class TerminatableStream<T extends TerminatableStream<T>> {
  // root-only fields, ignored for non-root instances
  private boolean terminated = false;
  private final List<Runnable> onClose;

  private final TerminatableStream<?> root;

  public TerminatableStream(TerminatableStream<?> previous) {
    if (previous == null) {
      root = null;
      onClose = new ArrayList<>();
    } else {
      root = previous;
      onClose = null;
    }
  }

  void throwIfTerminated() {
    if (root != null) {
      root.throwIfTerminated();
    } else if (terminated) {
      throw new IllegalStateException("Stream already terminated, can't be modified or used");
    }
  }

  // note that not all terminals directly call this, but they must use it indirectly
  void terminate() {
    if (root == null) {
      throwIfTerminated();
      terminated = true;
    } else {
      root.terminate();
    }
  }

  public T onClose(Runnable closeHandler) {
    if (root == null) {
      onClose.add(closeHandler);
    } else {
      root.onClose(closeHandler);
    }

    return (T) this;
  }

  public void close() {
    if (root == null) {
      terminated = true;
      runClosers();
    } else {
      root.close();
    }
  }

  private void runClosers() {
    ArrayList<Throwable> throwables = new ArrayList<>();
    onClose.forEach(
        runnable -> {
          try {
            runnable.run();
          } catch (Throwable e) {
            throwables.add(e);
          }
        });
    onClose.clear();

    if (!throwables.isEmpty()) {
      Throwable e = throwables.get(0);
      for (int i = 1, size = throwables.size(); i < size; ++i) {
        Throwable suppressed = throwables.get(i);
        if (suppressed != e) {
          e.addSuppressed(suppressed);
        }
      }

      if (e instanceof RuntimeException) {
        throw (RuntimeException) e;
      }
      if (e instanceof Error) {
        throw (Error) e;
      }
      assert false : "Couldn't have caught this exception from a Runnable! " + e;
    }
  }
}
