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

/**
 * This file contains code that is shared by both sim implementations (signals
 * and no-signals).
 */

#include "os/mynewt.h"

#include <hal/hal_bsp.h>

#ifdef __APPLE__
#define _XOPEN_SOURCE
#endif

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/time.h>
#include <assert.h>
#include "sim/sim.h"
#include "sim_priv.h"

#define sim_setjmp(__jb) sigsetjmp(__jb, 0)
#define sim_longjmp(__jb, __ret) siglongjmp(__jb, __ret)

pid_t sim_pid;

void
sim_switch_tasks(void)
{
    struct os_task *t, *next_t;
    struct stack_frame *sf;
    int rc;

    OS_ASSERT_CRITICAL();

    t = os_sched_get_current_task();
    next_t = os_sched_next_task();
    if (t == next_t) {
        /*
         * Context switch not needed - just return.
         */
        return;
    }

    if (t) {
        sf = (struct stack_frame *) t->t_stackptr;

        rc = sim_setjmp(sf->sf_jb);
        if (rc != 0) {
            OS_ASSERT_CRITICAL();
            return;
        }
    }

    os_sched_ctx_sw_hook(next_t);

    os_sched_set_current_task(next_t);

    sf = (struct stack_frame *) next_t->t_stackptr;
    sim_longjmp(sf->sf_jb, 1);
}

void
sim_tick(void)
{
    struct timeval time_now, time_diff;
    int ticks;

    static struct timeval time_last;
    static int time_inited;

    OS_ASSERT_CRITICAL();

    if (!time_inited) {
        gettimeofday(&time_last, NULL);
        time_inited = 1;
    }

    gettimeofday(&time_now, NULL);
    if (timercmp(&time_now, &time_last, <)) {
        /*
         * System time going backwards.
         */
        time_last = time_now;
    } else {
        timersub(&time_now, &time_last, &time_diff);

        ticks = time_diff.tv_sec * OS_TICKS_PER_SEC;
        ticks += time_diff.tv_usec / OS_USEC_PER_TICK;

        /*
         * Update 'time_last' but account for the remainder usecs that did not
         * contribute towards whole 'ticks'.
         */
        time_diff.tv_sec = 0;
        time_diff.tv_usec %= OS_USEC_PER_TICK;
        timersub(&time_now, &time_diff, &time_last);

        os_time_advance(ticks);
    }
}

static void
sim_start_timer(void)
{
    struct itimerval it;
    int rc;

    memset(&it, 0, sizeof(it));
    it.it_value.tv_sec = 0;
    it.it_value.tv_usec = OS_USEC_PER_TICK;
    it.it_interval.tv_sec = 0;
    it.it_interval.tv_usec = OS_USEC_PER_TICK;

    rc = setitimer(ITIMER_REAL, &it, NULL);
    assert(rc == 0);
}

static void
sim_stop_timer(void)
{
    struct itimerval it;
    int rc;

    memset(&it, 0, sizeof(it));

    rc = setitimer(ITIMER_REAL, &it, NULL);
    assert(rc == 0);
}

/*
 * Called from 'os_arch_frame_init()' when setjmp returns indirectly via
 * longjmp. The return value of setjmp is passed to this function as 'rc'.
 */
void
sim_task_start(struct stack_frame *sf, int rc)
{
    struct os_task *task;

    /*
     * Interrupts are disabled when a task starts executing. This happens in
     * two different ways:
     * - via sim_os_start() for the first task.
     * - via os_sched() for all other tasks.
     *
     * Enable interrupts before starting the task.
     */
    OS_EXIT_CRITICAL(0);

    task = sf->sf_task;
    task->t_func(task->t_arg);

    /* If a unit test is executing, the test is complete when a task handler
     * returns.
     */
#if MYNEWT_VAL(SELFTEST)
    void tu_restart(void);
    tu_restart();
#else
    /* Otherwise, a task handler should never return. */
    assert(0);
#endif
}

os_stack_t *
sim_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size)
{
    struct stack_frame *sf;

    sf = (struct stack_frame *) ((uint8_t *) stack_top - sizeof(*sf));
    sf->sf_task = t;

    os_arch_frame_init(sf);

    return ((os_stack_t *)sf);
}

os_error_t
sim_os_start(void)
{
    struct stack_frame *sf;
    struct os_task *t;
    os_sr_t sr;

    /*
     * Disable interrupts before enabling any interrupt sources. Pending
     * interrupts will be recognized when the first task starts executing.
     */
    OS_ENTER_CRITICAL(sr);
    assert(sr == 0);

    /* Enable the interrupt sources */
    sim_start_timer();

    t = os_sched_next_task();
    os_sched_set_current_task(t);

    g_os_started = 1;

    sf = (struct stack_frame *) t->t_stackptr;
    sim_longjmp(sf->sf_jb, 1);

    return 0;
}

/**
 * Stops the tick timer and clears the "started" flag.  This function is only
 * implemented for sim.
 */
void
sim_os_stop(void)
{
    sim_stop_timer();
    sim_signals_cleanup();
    g_os_started = 0;
}

os_error_t
sim_os_init(void)
{
    sim_pid = getpid();
    g_current_task = NULL;

    STAILQ_INIT(&g_os_task_list);
    TAILQ_INIT(&g_os_run_list);
    TAILQ_INIT(&g_os_sleep_list);

    sim_signals_init();

    os_init_idle_task();

    return OS_OK;
}
