/*
 * 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
 *
 *  https://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.
 *
 * Other licenses:
 * -----------------------------------------------------------------------------
 * Commercial licenses for this work are available. These replace the above
 * Apache-2.0 license and offer limited warranties, support, maintenance, and
 * commercial database integrations.
 *
 * For more information, please visit: https://www.jooq.org/legal/licensing
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package org.jooq;

import java.util.function.Consumer;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

/**
 * An SPI to allow for overriding the default implementation of
 * {@link Subscriber} creation in jOOQ.
 * <p>
 * This SPI can be used to override jOOQ's internal creation of
 * {@link Subscriber} instances, typically used to create reactor style
 * context-aware {@link Subscriber} instances. Whatever the
 * {@link #context(Subscriber)} is, it will be propagated to additional
 * {@link #subscriber(Consumer, Consumer, Consumer, Runnable, Object)} calls.
 *
 * @author Lukas Eder
 */
public interface SubscriberProvider<C> {

    /**
     * Create an empty context.
     */
    @Nullable
    C context();

    /**
     * Extract a context from an existing {@link Subscriber}.
     */
    @Nullable
    C context(Subscriber<?> subscriber);

    /**
     * Create a new subscriber from its component implementations and a previous
     * context.
     *
     * @param onSubscribe The implementation of
     *            {@link Subscriber#onSubscribe(Subscription)}
     * @param onNext The implementation of {@link Subscriber#onNext(Object)}
     * @param onError The implementation of
     *            {@link Subscriber#onError(Throwable)}
     * @param onComplete The implementation of {@link Subscriber#onComplete()}
     * @param context The {@link #context()}
     */
    @NotNull
    <T> Subscriber<T> subscriber(
        Consumer<? super Subscription> onSubscribe,
        Consumer<? super T> onNext,
        Consumer<? super Throwable> onError,
        Runnable onComplete,
        C context
    );
}
