/*
 * Copyright 2015 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.onlab.util;

import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Base implementation of an item accumulator. It allows triggering based on
 * item inter-arrival time threshold, maximum batch life threshold and maximum
 * batch size.
 */
public abstract class AbstractAccumulator<T> implements Accumulator<T> {

    private Logger log = LoggerFactory.getLogger(AbstractAccumulator.class);

    private final Timer timer;
    private final int maxItems;
    private final int maxBatchMillis;
    private final int maxIdleMillis;

    private TimerTask idleTask = new ProcessorTask();
    private TimerTask maxTask = new ProcessorTask();

    private List<T> items = Lists.newArrayList();

    /**
     * Creates an item accumulator capable of triggering on the specified
     * thresholds.
     *
     * @param timer               timer to use for scheduling check-points
     * @param maxItems            maximum number of items to accumulate before
     *                            processing is triggered
     * @param maxBatchMillis      maximum number of millis allowed since the first
     *                            item before processing is triggered
     * @param maxIdleMillis       maximum number millis between items before
     *                            processing is triggered
     */
    protected AbstractAccumulator(Timer timer, int maxItems,
                                  int maxBatchMillis, int maxIdleMillis) {
        this.timer = checkNotNull(timer, "Timer cannot be null");

        checkArgument(maxItems > 1, "Maximum number of items must be > 1");
        checkArgument(maxBatchMillis > 0, "Maximum millis must be positive");
        checkArgument(maxIdleMillis > 0, "Maximum idle millis must be positive");

        this.maxItems = maxItems;
        this.maxBatchMillis = maxBatchMillis;
        this.maxIdleMillis = maxIdleMillis;
    }

    @Override
    public synchronized void add(T item) {
        idleTask = cancelIfActive(idleTask);
        items.add(checkNotNull(item, "Item cannot be null"));

        // Did we hit the max item threshold?
        if (items.size() >= maxItems) {
            maxTask = cancelIfActive(maxTask);
            schedule(1);
        } else {
            // Otherwise, schedule idle task and if this is a first item
            // also schedule the max batch age task.
            idleTask = schedule(maxIdleMillis);
            if (items.size() == 1) {
                maxTask = schedule(maxBatchMillis);
            }
        }
    }

    // Schedules a new processor task given number of millis in the future.
    private TimerTask schedule(int millis) {
        TimerTask task = new ProcessorTask();
        timer.schedule(task, millis);
        return task;
    }

    // Cancels the specified task if it is active.
    private TimerTask cancelIfActive(TimerTask task) {
        if (task != null) {
            task.cancel();
        }
        return task;
    }

    // Task for triggering processing of accumulated items
    private class ProcessorTask extends TimerTask {
        @Override
        public void run() {
            idleTask = cancelIfActive(idleTask);
            if (isReady()) {
                try {
                    maxTask = cancelIfActive(maxTask);
                    processItems(finalizeCurrentBatch());
                } catch (Exception e) {
                    log.warn("Unable to process batch due to {}", e);
                }
            } else {
                idleTask = schedule(maxIdleMillis);
            }
        }
    }

    // Demotes and returns the current batch of items and promotes a new one.
    private synchronized List<T> finalizeCurrentBatch() {
        List<T> toBeProcessed = items;
        items = Lists.newArrayList();
        return toBeProcessed;
    }

    @Override
    public boolean isReady() {
        return true;
    }

    /**
     * Returns the backing timer.
     *
     * @return backing timer
     */
    public Timer timer() {
        return timer;
    }

    /**
     * Returns the maximum number of items allowed to accumulate before
     * processing is triggered.
     *
     * @return max number of items
     */
    public int maxItems() {
        return maxItems;
    }

    /**
     * Returns the maximum number of millis allowed to expire since the first
     * item before processing is triggered.
     *
     * @return max number of millis a batch is allowed to last
     */
    public int maxBatchMillis() {
        return maxBatchMillis;
    }

    /**
     * Returns the maximum number of millis allowed to expire since the last
     * item arrival before processing is triggered.
     *
     * @return max number of millis since the last item
     */
    public int maxIdleMillis() {
        return maxIdleMillis;
    }

}
