/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.ode.scheduler.simple;

import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.ode.utils.stl.CollectionsX;
import org.apache.ode.utils.stl.MemberOfFunction;

/**
 * Implements the "todo" queue and prioritized scheduling mechanism.
 *
 * @author mszefler
 * @author Maciej Szefler ( m s z e f l e r @ g m a i l . c o m )
 *
 */
class SchedulerThread implements Runnable {

    private static final Logger __log = LoggerFactory.getLogger(SchedulerThread.class);

    private static final int TODO_QUEUE_INITIAL_CAPACITY = 200;

    /** Jobs ready for immediate execution. */
    private PriorityBlockingQueue<Task> _todo;

    /** Lock for managing the queue */
    private ReentrantLock _lock = new ReentrantLock();

    private Condition _activity = _lock.newCondition();

    private volatile boolean _done;

    private TaskRunner _taskrunner;

    private Thread _thread;

    SchedulerThread(TaskRunner runner) {
        _todo = new PriorityBlockingQueue<Task>(TODO_QUEUE_INITIAL_CAPACITY,
                new JobComparatorByDate());
        _taskrunner = runner;
    }

    void start() {
        if (_thread != null)
            return;

        _done = false;
        _thread = new Thread(this, "OdeScheduler");
        _thread.start();
    }

    /**
     * Shutdown the thread.
     */
    void stop() {
        if (_thread == null)
            return;

        _done = true;
        _lock.lock();
        try {
            _activity.signal();
        } finally {
            _lock.unlock();

        }

        while (_thread != null)
            try {
                _thread.join();
                _thread = null;
            } catch (InterruptedException e) {
                ;
            }

    }

    /**
     * Add a job to the todo queue.
     *
     * @param job
     */
    void enqueue(Task task) {
        _lock.lock();
        try {
            _todo.add(task);
            _activity.signal();
        } finally {
            _lock.unlock();
        }
    }

    /**
     * Remove a job to the todo queue.
     *
     * @param job
     */
    void dequeue(Task task) {
        _lock.lock();
        try {
            _todo.remove(task);
            _activity.signal();
        } finally {
            _lock.unlock();
        }
    }

    /**
     * Get the size of the todo queue.
     *
     * @return
     */
    public int size() {
        return _todo.size();
    }

    /**
     * Pop items off the todo queue, and send them to the task runner for processing.
     */
    public void run() {
        while (!_done) {
            _lock.lock();
            try {
                long nextjob;
                while ((nextjob = nextJobTime()) > 0 && !_done)
                    _activity.await(nextjob, TimeUnit.MILLISECONDS);

                if (!_done && nextjob == 0) {
                    Task task = _todo.take();
                    _taskrunner.runTask(task);

                }
            } catch (InterruptedException ex) {
                ; // ignore
            } finally {
                _lock.unlock();
            }
        }
    }

    /**
     * Calculate the time until the next available job.
     *
     * @return time until next job, 0 if one is one is scheduled to go, and some
     *         really large number if there are no jobs to speak of
     */
    private long nextJobTime() {
        assert _lock.isLocked();

        Task job = _todo.peek();
        if (job == null)
            return Long.MAX_VALUE;

        return Math.max(0, job.schedDate - System.currentTimeMillis());
    }

    /**
     * Remove the tasks of a given type from the list.
     * @param tasktype type of task
     */
    public void clearTasks(final Class<? extends Task> tasktype) {
        _lock.lock();
        try {
            CollectionsX.remove_if(_todo, new MemberOfFunction<Task>() {
                @Override
                public boolean isMember(Task o) {
                    return tasktype.isAssignableFrom(o.getClass());
                }

            });
        } finally {
            _lock.unlock();
        }
    }
}
