package cc.redberry.pipe.util;

import cc.redberry.pipe.OutputPortCloseable;
import cc.redberry.pipe.OutputPort;

//TODO much better implementation is possible
public class FlatteningOutputPort<T> implements OutputPortCloseable<T> {
    private OutputPort<? extends OutputPort<? extends T>> opop;
    private OutputPort<? extends T> op;

    public FlatteningOutputPort(OutputPort<? extends OutputPort<? extends T>> opop) {
        this.opop = opop;
    }

    @Override
    public synchronized T take() {
        T result;

        //First invocation
        if (op == null)
            op = opop.take();

        do {
            if (op == null)
                return null;

            result = op.take();

            if (result == null)
                op = opop.take();

        } while (result == null);

        return result;
    }

    @Override
    public synchronized void close() {
        if (opop instanceof OutputPortCloseable)
            ((OutputPortCloseable) opop).close();
        if (op != null && op instanceof OutputPortCloseable)
            ((OutputPortCloseable) op).close();
        opop = null;
    }
}
