/*
 * 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 <assert.h>
#include "os/mynewt.h"

CTASSERT(sizeof(os_time_t) == 4);

#define OS_USEC_PER_TICK    (1000000 / OS_TICKS_PER_SEC)

os_time_t g_os_time;

static STAILQ_HEAD(, os_time_change_listener) os_time_change_listeners =
    STAILQ_HEAD_INITIALIZER(os_time_change_listeners);

/*
 * Time-of-day collateral.
 */
static struct {
    os_time_t ostime;
    struct os_timeval uptime;
    struct os_timeval utctime;
    struct os_timezone timezone;
} basetod;

static void
os_deltatime(os_time_t delta, const struct os_timeval *base,
    struct os_timeval *result)
{
    struct os_timeval tvdelta;

    tvdelta.tv_sec = delta / OS_TICKS_PER_SEC;
    tvdelta.tv_usec = (delta % OS_TICKS_PER_SEC) * OS_USEC_PER_TICK;
    os_timeradd(base, &tvdelta, result);
}

os_time_t
os_time_get(void)
{
    return (g_os_time);
}

#if MYNEWT_VAL(OS_SCHEDULING)
static void
os_time_tick(int ticks)
{
    os_sr_t sr;
    os_time_t delta, prev_os_time;

    assert(ticks >= 0);

    OS_ENTER_CRITICAL(sr);
    prev_os_time = g_os_time;
    g_os_time += ticks;

    /*
     * Update 'basetod' when 'g_os_time' crosses the 0x00000000 and
     * 0x80000000 thresholds.
     */
    if ((prev_os_time ^ g_os_time) >> 31) {
        delta = g_os_time - basetod.ostime;
        os_deltatime(delta, &basetod.uptime, &basetod.uptime);
        os_deltatime(delta, &basetod.utctime, &basetod.utctime);
        basetod.ostime = g_os_time;
    }
    OS_EXIT_CRITICAL(sr);
}

void
os_time_advance(int ticks)
{
    assert(ticks >= 0);

    if (ticks > 0) {
        if (!os_started()) {
            g_os_time += ticks;
        } else {
            os_time_tick(ticks);
            os_callout_tick();
            os_sched_os_timer_exp();
            os_sched(NULL);
        }
    }
}

void
os_time_delay(os_time_t osticks)
{
    os_sr_t sr;

    if (osticks > 0) {
        OS_ENTER_CRITICAL(sr);
        os_sched_sleep(os_sched_get_current_task(), (os_time_t)osticks);
        OS_EXIT_CRITICAL(sr);
        os_sched(NULL);
    }
}

#else

void
os_time_advance(int ticks)
{
    g_os_time += ticks;
}

void
os_time_delay(os_time_t osticks)
{
}

#endif

/**
 * Searches the list of registered time change listeners for the specified
 * entry.
 *
 * @param listener              The listener to find.
 * @param out_prev              On success, the specified listener's
 *                                  predecessor gets written here.  Pass NULL
 *                                  if you do not require this information.
 *
 * @return                      0 if the specified listener was found;
 *                              SYS_ENOENT if the listener is not present.
 */
static int
os_time_change_listener_find(const struct os_time_change_listener *listener,
                             struct os_time_change_listener **out_prev)
{
    struct os_time_change_listener *prev;
    struct os_time_change_listener *cur;

    prev = NULL;
    STAILQ_FOREACH(cur, &os_time_change_listeners, tcl_next) {
        if (cur == listener) {
            break;
        }

        prev = cur;
    }

    if (cur == NULL) {
        return SYS_ENOENT;
    }

    if (out_prev != NULL) {
        *out_prev = prev;
    }

    return 0;
}

void
os_time_change_listen(struct os_time_change_listener *listener)
{
#if MYNEWT_VAL(OS_TIME_DEBUG)
    assert(listener->tcl_fn != NULL);
    assert(os_time_change_listener_find(listener, NULL) == SYS_ENOENT);
#endif

    STAILQ_INSERT_TAIL(&os_time_change_listeners, listener, tcl_next);
}

int
os_time_change_remove(const struct os_time_change_listener *listener)
{
    struct os_time_change_listener *prev;
    int rc;

    rc = os_time_change_listener_find(listener, &prev);
    if (rc != 0) {
        return rc;
    }

    if (prev == NULL) {
        STAILQ_REMOVE_HEAD(&os_time_change_listeners, tcl_next);
    } else {
        STAILQ_NEXT(prev, tcl_next) = STAILQ_NEXT(listener, tcl_next);
    }

    return 0;
}

static void
os_time_change_notify(const struct os_time_change_info *info)
{
    struct os_time_change_listener *listener;

    STAILQ_FOREACH(listener, &os_time_change_listeners, tcl_next) {
        listener->tcl_fn(info, listener->tcl_arg);
    }
}

static int
os_time_populate_info(struct os_time_change_info *info,
                      const struct os_timeval *new_tv,
                      const struct os_timezone *new_tz)
{
    if (new_tv == NULL && new_tz == NULL) {
        return SYS_EINVAL;
    }

    if (new_tv == NULL) {
        new_tv = &basetod.utctime;
    }
    if (new_tz == NULL) {
        new_tz = &basetod.timezone;
    }

    info->tci_prev_tv = &basetod.utctime;
    info->tci_cur_tv = new_tv;
    info->tci_prev_tz = &basetod.timezone;
    info->tci_cur_tz = new_tz;
    info->tci_newly_synced = !os_time_is_set();

    return 0;
}

int
os_settimeofday(struct os_timeval *utctime, struct os_timezone *tz)
{
    os_sr_t sr;
    os_time_t delta;
    struct os_time_change_info info;
    bool notify;
    int rc;

    OS_ENTER_CRITICAL(sr);

    rc = os_time_populate_info(&info, utctime, tz);
    notify = rc == 0;

    if (utctime != NULL) {
        /*
         * Update all time-of-day base values.
         */
        delta = os_time_get() - basetod.ostime;
        os_deltatime(delta, &basetod.uptime, &basetod.uptime);
        basetod.utctime = *utctime;
        basetod.ostime += delta;
    }

    if (tz != NULL) {
        basetod.timezone = *tz;
    }

    OS_EXIT_CRITICAL(sr);

    /* Notify all listeners of time change. */
    if (notify) {
        os_time_change_notify(&info);
    }

    return (0);
}

int
os_gettimeofday(struct os_timeval *tv, struct os_timezone *tz)
{
    os_sr_t sr;
    os_time_t delta;

    OS_ENTER_CRITICAL(sr);
    if (tv != NULL) {
        delta = os_time_get() - basetod.ostime;
        os_deltatime(delta, &basetod.utctime, tv);
    }

    if (tz != NULL) {
        *tz = basetod.timezone;
    }
    OS_EXIT_CRITICAL(sr);

    return (0);
}

bool
os_time_is_set(void)
{
    return basetod.utctime.tv_sec > 0;
}

void
os_get_uptime(struct os_timeval *tvp)
{
  struct os_timeval tv;
  os_time_t delta;
  os_sr_t sr;
  os_time_t ostime;

  OS_ENTER_CRITICAL(sr);
  tv = basetod.uptime;
  ostime = basetod.ostime;
  delta = os_time_get() - ostime;
  OS_EXIT_CRITICAL(sr);

  os_deltatime(delta, &tv, tvp);
}

int64_t
os_get_uptime_usec(void)
{
  struct os_timeval tv;

  os_get_uptime(&tv);

  return (tv.tv_sec * 1000000 + tv.tv_usec);
}

int
os_time_ms_to_ticks(uint32_t ms, os_time_t *out_ticks)
{
    uint64_t ticks;

#if OS_TICKS_PER_SEC == 1000
    *out_ticks = ms;
    return 0;
#endif

    static_assert(OS_TICKS_PER_SEC <= UINT32_MAX,
                  "OS_TICKS_PER_SEC must be <= UINT32_MAX");

    ticks = ((uint64_t)ms * OS_TICKS_PER_SEC) / 1000;
    if (ticks > UINT32_MAX) {
        return OS_EINVAL;
    }

    *out_ticks = ticks;
    return 0;
}

int
os_time_ticks_to_ms(os_time_t ticks, uint32_t *out_ms)
{
    uint64_t ms;

#if OS_TICKS_PER_SEC == 1000
    *out_ms = ticks;
    return 0;
#endif

    ms = ((uint64_t)ticks * 1000) / OS_TICKS_PER_SEC;
    if (ms > UINT32_MAX) {
        return OS_EINVAL;
    }

    *out_ms = ms;

    return 0;
}
