package org.implab.gradle.common.core.lang;

import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;

public final class Deferred<T> {
    private final List<Consumer<? super T>> listeners = new LinkedList<>();
    private T value;
    private boolean resolved = false;

    public boolean resolved() {
        return resolved;
    }

    public T value() {
        if (!resolved)
            throw new IllegalStateException();
        return value;
    }

    public void resolve(T value) {
        if (resolved) {
            throw new IllegalStateException("Already resolved");
        }
        this.value = value;
        this.resolved = true;
        listeners.forEach(listener -> listener.accept(value));
        listeners.clear();
    }

    public void whenResolved(Consumer<? super T> listener) {
        if (resolved) {
            listener.accept(value);
        } else {
            listeners.add(listener);
        }
    }
}
