/*
 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.incubator.http.internal.common;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
import java.util.function.BiConsumer;
import java.util.function.Function;

import static java.util.Objects.requireNonNull;
import java.util.concurrent.atomic.AtomicLong;

/*
 * A CompletableFuture which does not allow any obtrusion logic.
 * All methods of CompletionStage return instances of this class.
 */
public final class MinimalFuture<T> extends CompletableFuture<T> {

    @FunctionalInterface
    public interface ExceptionalSupplier<U> {
        U get() throws Throwable;
    }

    final static AtomicLong TOKENS = new AtomicLong();
    final long id;

    public static <U> MinimalFuture<U> completedFuture(U value) {
        MinimalFuture<U> f = new MinimalFuture<>();
        f.complete(value);
        return f;
    }

    public static <U> CompletableFuture<U> failedFuture(Throwable ex) {
        requireNonNull(ex);
        MinimalFuture<U> f = new MinimalFuture<>();
        f.completeExceptionally(ex);
        return f;
    }

    public static <U> CompletableFuture<U> supply(ExceptionalSupplier<U> supplier) {
        CompletableFuture<U> cf = new MinimalFuture<>();
        try {
            U value = supplier.get();
            cf.complete(value);
        } catch (Throwable t) {
            cf.completeExceptionally(t);
        }
        return cf;
    }

    public static <U> CompletableFuture<U> supply(ExceptionalSupplier<U> supplier, Executor executor) {
        CompletableFuture<U> cf = new MinimalFuture<>();
        cf.completeAsync( () -> {
            try {
                return supplier.get();
            } catch (Throwable ex) {
                throw new CompletionException(ex);
            }
        }, executor);
        return cf;
    }

    public MinimalFuture() {
        super();
        this.id = TOKENS.incrementAndGet();
    }

    /**
     * Creates a defensive copy of the given {@code CompletionStage}.
     *
     * <p> Might be useful both for producers and consumers of {@code
     * CompletionStage}s.
     *
     * <p> Producers are protected from possible uncontrolled modifications
     * (cancellation, completion, obtrusion, etc.) as well as from executing
     * unknown potentially lengthy or faulty dependants in the given {@code
     * CompletionStage}'s default execution facility or synchronously.
     *
     * <p> Consumers are protected from some of the aspects of misbehaving
     * implementations (e.g. accepting results, applying functions, running
     * tasks, etc. more than once or escape of a reference to their private
     * executor, etc.) by providing a reliable proxy they use instead.
     *
     * @param src
     *         the {@code CompletionStage} to make a copy from
     * @param executor
     *         the executor used to propagate the completion
     * @param <T>
     *         the type of the {@code CompletionStage}'s result
     *
     * @return a copy of the given stage
     */
    public static <T> MinimalFuture<T> copy(CompletionStage<T> src,
                                            Executor executor) {
        MinimalFuture<T> copy = new MinimalFuture<>();
        BiConsumer<T, Throwable> relay =
                (result, error) -> {
                    if (error != null) {
                        copy.completeExceptionally(error);
                    } else {
                        copy.complete(result);
                    }
                };

        if (src.getClass() == CompletableFuture.class) {
            // No subclasses! Strictly genuine CompletableFuture.
            src.whenCompleteAsync(relay, executor);
            return copy;
        } else {
            // Don't give our executor away to an unknown CS!
            src.whenComplete(relay);
            return (MinimalFuture<T>)
                    copy.thenApplyAsync(Function.identity(), executor);
        }
    }

    public <U> MinimalFuture<U> newIncompleteFuture() {
        return new MinimalFuture<>();
    }

    @Override
    public void obtrudeValue(T value) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void obtrudeException(Throwable ex) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String toString() {
        return super.toString() + " (id=" + id +")";
    }
}
