/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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 org.onosproject.store.service;

import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

import com.google.common.collect.ImmutableList;

/**
 * Distributed Work Queue primitive.
 * <p>
 * Work queue serves as a buffer allowing producers to {@link #addMultiple(Collection) add} tasks and consumers
 * to {@link #take() take} tasks to process.
 * <p>
 * In the system each task is tracked via its unique task identifier which is returned when a task is taken.
 * Work queue guarantees that a task can be taken by only one consumer at a time. Once it finishes processing a
 * consumer must invoke the {@link #complete(Collection) complete} method to mark the task(s) as completed.
 * Tasks thus completed are removed from the queue. If a consumer unexpectedly terminates before it can complete
 * all its tasks are returned back to the queue so that other consumers can pick them up. Since there is a distinct
 * possibility that tasks could be processed more than once (under failure conditions), care should be taken to ensure
 * task processing logic is idempotent.
 *
 * @param <E> task payload type.
 */
public interface WorkQueue<E> extends DistributedPrimitive {

    @Override
    default DistributedPrimitive.Type primitiveType() {
        return DistributedPrimitive.Type.WORK_QUEUE;
    }

    /**
     * Adds a collection of tasks to the work queue.
     * @param items collection of task items
     * @return future that is completed when the operation completes
     */
    CompletableFuture<Void> addMultiple(Collection<E> items);

    /**
     * Picks up multiple tasks from the work queue to work on.
     * <p>
     * Tasks that are taken remain invisible to other consumers as long as the consumer stays alive.
     * If a consumer unexpectedly terminates before {@link #complete(String...) completing} the task,
     * the task becomes visible again to other consumers to process.
     * @param maxItems maximum number of items to take from the queue. The actual number of tasks returned
     * can be at the max this number
     * @return future for the tasks. The future can be completed with an empty collection if there are no
     * unassigned tasks in the work queue
     */
    CompletableFuture<Collection<Task<E>>> take(int maxItems);

    /**
     * Completes a collection of tasks.
     * @param taskIds ids of tasks to complete
     * @return future that is completed when the operation completes
     */
    CompletableFuture<Void> complete(Collection<String> taskIds);

    /**
     * Registers a task processing callback to be automatically invoked when new tasks are
     * added to the work queue.
     * @param taskProcessor task processing callback
     * @param parallelism max tasks that can be processed in parallel
     * @param executor executor to use for processing the tasks
     * @return future that is completed when the operation completes
     */
    CompletableFuture<Void> registerTaskProcessor(Consumer<E> taskProcessor,
                                                  int parallelism,
                                                  Executor executor);

    /**
     * Stops automatically processing tasks from work queue. This call nullifies the effect of a
     * previous {@link #registerTaskProcessor registerTaskProcessor} call.
     * @return future that is completed when the operation completes
     */
    CompletableFuture<Void> stopProcessing();

    /**
     * Returns work queue statistics.
     * @return future that is completed with work queue stats when the operation completes
     */
    CompletableFuture<WorkQueueStats> stats();

    /**
     * Completes a collection of tasks.
     * @param taskIds var arg list of task ids
     * @return future that is completed when the operation completes
     */
    default CompletableFuture<Void> complete(String... taskIds) {
        return complete(Arrays.asList(taskIds));
    }

    /**
     * Adds a single task to the work queue.
     * @param item task item
     * @return future that is completed when the operation completes
     */
    default CompletableFuture<Void> addOne(E item) {
        return addMultiple(ImmutableList.of(item));
    }

    /**
     * Picks up a single task from the work queue to work on.
     * <p>
     * Tasks that are taken remain invisible to other consumers as long as the consumer stays alive.
     * If a consumer unexpectedly terminates before {@link #complete(String...) completing} the task,
     * the task becomes visible again to other consumers to process.
     * @return future for the task. The future can be completed with null, if there are no
     * unassigned tasks in the work queue
     */
    default CompletableFuture<Task<E>> take() {
        return this.take(1).thenApply(tasks -> tasks.isEmpty() ? null : tasks.iterator().next());
    }
}