/*
 * 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 <nuttx/config.h>
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#include <time.h>
#include <signal.h>

#include "nimble/nimble_npl.h"

#ifndef CONFIG_NIMBLE_CALLOUT_THREAD_STACKSIZE
#define CONFIG_NIMBLE_CALLOUT_THREAD_STACKSIZE 1024
#endif

struct ble_npl_callout *pending_callout = NULL;

bool thread_started = false;
pthread_t callout_thread;
pthread_mutex_t callout_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t callout_cond = PTHREAD_COND_INITIALIZER;

static pthread_addr_t
callout_handler(pthread_addr_t arg)
{
    struct ble_npl_callout *c;

    while (true) {
        pthread_mutex_lock(&callout_mutex);
        while (!pending_callout) {
          pthread_cond_wait(&callout_cond, &callout_mutex);
        }

        c = pending_callout;
        pending_callout = NULL;
        pthread_mutex_unlock(&callout_mutex);

        /* Invoke callback */

        if (c->c_evq) {
            ble_npl_eventq_put(c->c_evq, &c->c_ev);
        } else {
            c->c_ev.ev_cb(&c->c_ev);
        }
    }

    return NULL;
}

static void
ble_npl_callout_timer_cb(union sigval sv)
{
    struct ble_npl_callout *c = (struct ble_npl_callout *)sv.sival_ptr;
    assert(c);

    pthread_mutex_lock(&callout_mutex);
    pending_callout = c;
    pthread_cond_signal(&callout_cond);
    pthread_mutex_unlock(&callout_mutex);
}

void
ble_npl_callout_init(struct ble_npl_callout *c,
                     struct ble_npl_eventq *evq,
                     ble_npl_event_fn *ev_cb,
                     void *ev_arg)
{
    struct sigevent         event;

    if (!thread_started) {
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setstacksize(&attr, CONFIG_NIMBLE_CALLOUT_THREAD_STACKSIZE);
        pthread_create(&callout_thread, &attr, callout_handler, NULL);
        pthread_setname_np(callout_thread, "ble_npl_callout");
        thread_started = true;
    }

    /* Initialize the callout. */
    memset(c, 0, sizeof(*c));
    c->c_ev.ev_cb = ev_cb;
    c->c_ev.ev_arg = ev_arg;
    c->c_evq = evq;
    c->c_active = false;

    event.sigev_notify = SIGEV_THREAD;
    event.sigev_value.sival_ptr = c;     // put callout obj in signal args
    event.sigev_notify_function = ble_npl_callout_timer_cb;
    event.sigev_notify_attributes = NULL;

    timer_create(CLOCK_REALTIME, &event, &c->c_timer);
}

bool
ble_npl_callout_is_active(struct ble_npl_callout *c)
{
    /* TODO: seek native posix method to determine whether timer_t is active.
       TODO: fix bug where one-shot timer is still active after fired. */

    return c->c_active;
}

int
ble_npl_callout_inited(struct ble_npl_callout *c)
{
    return (c->c_timer != NULL);
}

ble_npl_error_t
ble_npl_callout_reset(struct ble_npl_callout *c,
                      ble_npl_time_t ticks)
{
    struct itimerspec       its;

    if (ticks < 0) {
        return BLE_NPL_EINVAL;
    }

    if (ticks == 0) {
        ticks = 1;
    }

    c->c_ticks = ble_npl_time_get() + ticks;

    its.it_interval.tv_sec = 0;
    its.it_interval.tv_nsec = 0;                     /* one shot */
    its.it_value.tv_sec = (ticks / 1000);
    its.it_value.tv_nsec = (ticks % 1000) * 1000000; /* expiration */
    its.it_value.tv_nsec %= 1000000000;
    c->c_active = true;
    timer_settime(c->c_timer, 0, &its, NULL);

    return BLE_NPL_OK;
}

int
ble_npl_callout_queued(struct ble_npl_callout *c)
{
    struct itimerspec its;
    timer_gettime(c->c_timer, &its);

    return ((its.it_value.tv_sec > 0) ||
            (its.it_value.tv_nsec > 0));
}

void
ble_npl_callout_stop(struct ble_npl_callout *c)
{
    if (!ble_npl_callout_inited(c)) {
        return;
    }

    struct itimerspec its;
    its.it_interval.tv_sec = 0;
    its.it_interval.tv_nsec = 0;
    its.it_value.tv_sec = 0;
    its.it_value.tv_nsec = 0;
    timer_settime(c->c_timer, 0, &its, NULL);
    c->c_active = false;
}

ble_npl_time_t
ble_npl_callout_get_ticks(struct ble_npl_callout *co)
{
    return co->c_ticks;
}

void
ble_npl_callout_set_arg(struct ble_npl_callout *co, void *arg)
{
    co->c_ev.ev_arg = arg;
}

uint32_t
ble_npl_callout_remaining_ticks(struct ble_npl_callout *co,
                                ble_npl_time_t now)
{
    ble_npl_time_t rt;
    uint32_t exp;

    struct itimerspec its;
    timer_gettime(co->c_timer, &its);

    exp = its.it_value.tv_sec * 1000;

    if (exp > now) {
        rt = exp - now;
    } else {
        rt = 0;
    }

    return rt;
}
