/*
 * 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.
 */

#include "qpid/dispatch/timer.h"

#include "dispatch_private.h"
#include "server_private.h"
#include "timer_private.h"

#include "qpid/dispatch/alloc.h"
#include "qpid/dispatch/ctools.h"
#include "qpid/dispatch/atomic.h"

#include <proton/proactor.h>

#include <assert.h>
#include <stdio.h>


// timer state machine
//
// IDLE: initial state or state immediately after the callback finishes
// running.
//
// SCHEDULED: timer has been scheduled to run.  It is on the scheduled_timer
// list.  Valid next states are IDLE (if timer canceled), RUNNING, or DELETED.
//
// RUNNING: the timer callback is executing.  Valid next states are IDLE,
// SCHEDULED, BLOCKED or DELETED.  The address of the thread executing the
// callback is available in callback_thread
//
// BLOCKED: the callback is executing and another thread is blocked waiting for
// the callback to complete.  This state is used when cancelling or freeing a
// running timer.
//
// DELETED: final state.  There are no valid next states.
//
typedef enum {
    QD_TIMER_STATE_IDLE,
    QD_TIMER_STATE_SCHEDULED,
    QD_TIMER_STATE_RUNNING,
    QD_TIMER_STATE_BLOCKED,
    QD_TIMER_STATE_DELETED
} qd_timer_state_t;


struct qd_timer_t {
    DEQ_LINKS(qd_timer_t);
    qd_server_t      *server;
    qd_timer_cb_t     handler;
    void             *context;
    sys_cond_t       *condition;
    sys_atomic_t      ref_count; // referenced by user and when on scheduled list
    qd_timestamp_t    delta_time;
    qd_timer_state_t  state;
};

DEQ_DECLARE(qd_timer_t, qd_timer_list_t);

static sys_mutex_t     *lock = NULL;
static qd_timer_list_t  scheduled_timers = {0};

// thread currently running timer callbacks or 0 if callbacks are not running
static sys_thread_t    *callback_thread = 0;

/* Timers have relative delta_time measured from the previous timer.
 * The delta_time of the first timer on the queue is measured from timer_base.
 */
static qd_timestamp_t   time_base = 0;

ALLOC_DECLARE(qd_timer_t);
ALLOC_DEFINE(qd_timer_t);

/// For tests only
sys_mutex_t* qd_timer_lock() { return lock; }

//=========================================================================
// Private static functions
//=========================================================================

// returns true if timer removed from scheduled list
static bool timer_cancel_LH(qd_timer_t *timer)
{
    if (timer->state == QD_TIMER_STATE_SCHEDULED) {
        if (timer->next)
            timer->next->delta_time += timer->delta_time;
        DEQ_REMOVE(scheduled_timers, timer);
        timer->state = QD_TIMER_STATE_IDLE;
        return true;
    }
    return false;
}


/* Adjust timer's time_base and delays for the current time. */
static void timer_adjust_now_LH()
{
    qd_timestamp_t now = qd_timer_now();
    if (time_base != 0 && now > time_base) {
        qd_duration_t delta = now - time_base;
        /* Adjust timer delays by removing duration delta, starting from timer. */
        for (qd_timer_t *timer = DEQ_HEAD(scheduled_timers); delta > 0 && timer; timer = DEQ_NEXT(timer)) {
            if (timer->delta_time >= delta) {
                timer->delta_time -= delta;
                delta = 0;
            } else {
                delta -= timer->delta_time;
                timer->delta_time = 0; /* Ready to fire */
            }
        }
    }
    time_base = now;
}


static void timer_decref_LH(qd_timer_t *timer)
{
    assert(sys_atomic_get(&timer->ref_count) > 0);
    if (sys_atomic_dec(&timer->ref_count) == 1) {
        assert(timer->state != QD_TIMER_STATE_SCHEDULED);
        sys_cond_free(timer->condition);
        sys_atomic_destroy(&timer->ref_count);
        free_qd_timer_t(timer);
    }
}


//=========================================================================
// Public Functions from timer.h
//=========================================================================


qd_timer_t *qd_timer(qd_dispatch_t *qd, qd_timer_cb_t cb, void* context)
{
    qd_timer_t *timer = new_qd_timer_t();
    if (!timer)
        return 0;

    sys_cond_t *cond = sys_cond();
    if (!cond) {
        free_qd_timer_t(timer);
        return 0;
    }

    DEQ_ITEM_INIT(timer);

    timer->server     = qd ? qd->server : 0;
    timer->handler    = cb;
    timer->context    = context;
    timer->delta_time = 0;
    timer->condition  = cond;
    timer->state      = QD_TIMER_STATE_IDLE;
    sys_atomic_init(&timer->ref_count, 1);

    return timer;
}


void qd_timer_free(qd_timer_t *timer)
{
    if (!timer) return;

    sys_mutex_lock(lock);

    assert(timer->state != QD_TIMER_STATE_DELETED);  // double free!!!

    if (timer->state == QD_TIMER_STATE_RUNNING) {
        if (sys_thread_self() != callback_thread) {
            // Another thread is running the callback (see qd_timer_visit())
            // Wait until the callback finishes
            timer->state = QD_TIMER_STATE_BLOCKED;
            sys_cond_wait(timer->condition, lock);
        }
    }

    // we can safely free the timer since the callback is not running

    if (timer_cancel_LH(timer)) {
        // removed from scheduled_timers, so drop ref_count
        assert(sys_atomic_get(&timer->ref_count) > 1);  // expect caller holds a ref_count
        timer_decref_LH(timer);
    }

    timer->state = QD_TIMER_STATE_DELETED;
    timer_decref_LH(timer);  // now drop caller ref_count
    sys_mutex_unlock(lock);
}


__attribute__((weak)) // permit replacement by dummy implementation in unit_tests
qd_timestamp_t qd_timer_now()
{
    return pn_proactor_now_64();
}

void qd_timer_schedule(qd_timer_t *timer, qd_duration_t duration)
{
    sys_mutex_lock(lock);

    assert(timer->state != QD_TIMER_STATE_DELETED);
    const bool was_scheduled = timer_cancel_LH(timer);

    //
    // Find the insert point in the schedule.
    //
    timer_adjust_now_LH();   /* Adjust the timers for current time */

    /* Invariant: time_before == total time up to but not including ptr */
    qd_timer_t *ptr = DEQ_HEAD(scheduled_timers);
    qd_duration_t time_before = 0;
    while (ptr && time_before + ptr->delta_time < duration) {
        time_before += ptr->delta_time;
        ptr = ptr->next;
    }
    /* ptr is the first timer to exceed duration or NULL if we ran out */
    if (!ptr) {
        timer->delta_time = duration - time_before;
        DEQ_INSERT_TAIL(scheduled_timers, timer);
    } else {
        timer->delta_time = duration - time_before;
        ptr->delta_time -= timer->delta_time;
        ptr = ptr->prev;
        if (ptr)
            DEQ_INSERT_AFTER(scheduled_timers, timer, ptr);
        else
            DEQ_INSERT_HEAD(scheduled_timers, timer);
    }

    timer->state = QD_TIMER_STATE_SCHEDULED;
    if (!was_scheduled) {
        // scheduled_timers list reference:
        sys_atomic_inc(&timer->ref_count);
    }

    qd_timer_t *first = DEQ_HEAD(scheduled_timers);
    // Don't need to set timeout if qd_timer_visit is running on another thread now
    // Because qd_timer_visit will itself deal with rescheduling the timers
    if (!callback_thread) {
        qd_server_timeout(first->server, first->delta_time);
    }
    sys_mutex_unlock(lock);
}


void qd_timer_cancel(qd_timer_t *timer)
{
    sys_mutex_lock(lock);

    if (timer->state == QD_TIMER_STATE_RUNNING) {
        assert(sys_thread_self() != callback_thread);  // cancel within callback not allowed
        timer->state = QD_TIMER_STATE_BLOCKED;
        sys_cond_wait(timer->condition, lock);
    }

    // timer may have been resheduled before wait returns
    const bool need_decref = timer_cancel_LH(timer);
    timer->state = QD_TIMER_STATE_IDLE;
    if (need_decref)  // was on scheduled list
        timer_decref_LH(timer);

    sys_mutex_unlock(lock);
}


//=========================================================================
// Private Functions from timer_private.h
//=========================================================================


void qd_timer_initialize()
{
    lock = sys_mutex();
    DEQ_INIT(scheduled_timers);
    time_base = 0;
}


void qd_timer_finalize(void)
{
    sys_mutex_free(lock);
    lock = 0;
}


/* Execute all timers that are ready and set up next timeout. */
void qd_timer_visit()
{
    sys_mutex_lock(lock);
    callback_thread = sys_thread_self();
    timer_adjust_now_LH();
    qd_timer_t *timer = DEQ_HEAD(scheduled_timers);
    while (timer && timer->delta_time == 0) {
        // Remove timer from scheduled_timers but keep ref_count
        assert(timer->state == QD_TIMER_STATE_SCHEDULED);
        // note: still holding scheduled_timers refcount
        timer_cancel_LH(timer);
        timer->state = QD_TIMER_STATE_RUNNING;
        sys_mutex_unlock(lock);

        /* The callback may reschedule or delete the timer while the lock is
         * dropped.  Attempting to delete the timer now will cause the caller to
         * block until the callback is done.
         */
        timer->handler(timer->context);

        sys_mutex_lock(lock);
        if (timer->state == QD_TIMER_STATE_BLOCKED) {
            sys_cond_signal(timer->condition);
            // expect blocked caller sets timer->state
        } else if (timer->state == QD_TIMER_STATE_RUNNING) {
            timer->state = QD_TIMER_STATE_IDLE;
        }

        // now drop scheduled_timers reference:
        timer_decref_LH(timer);
        timer = DEQ_HEAD(scheduled_timers);
    }
    qd_timer_t *first = DEQ_HEAD(scheduled_timers);
    if (first) {
        qd_server_timeout(first->server, first->delta_time);
    }
    callback_thread = 0;
    sys_mutex_unlock(lock);
}
