#include "os_entry.h"

#undef SYS_LOG_DOMAIN
#define SYS_LOG_DOMAIN "OS"
#include "kernel/os_util.h"

#ifndef CONFIG_OS_THREAD_MAIN_STACK_SIZE
#define CONFIG_OS_THREAD_MAIN_STACK_SIZE 0x1C00
#endif

#ifndef CONFIG_OS_THREAD_MAIN_PRIORITY
#define CONFIG_OS_THREAD_MAIN_PRIORITY OS_PRIORITY_NORMAL
#endif

static unsigned s_int_nest;

static unsigned _port_interrupt_save(void)
{
    if (s_int_nest == 0)
    {
        os_interrupt_disable();
    }
    return s_int_nest++;
}

static void _port_interrupt_restore(unsigned nest)
{
    s_int_nest = nest;
    if (nest == 0)
    {
        os_interrupt_enable();
    }
}

static k_work_q_t *_port_get_work_q_hdl(void)
{
    struct os_thread_handle *thread_handle = os_thread_get_self();
    os_work_q_list_t *work_q_list = thread_handle->work_q_list;
    return &work_q_list->work_q_handle;
}

static void _port_thread_sleep(k_tick_t sleep_ticks)
{
    vTaskDelay(sleep_ticks);
}

int os_entry(os_work_fn work_route)
{
    static k_init_t const init_struct = {
        .malloc = os_malloc,
        .free = os_free,
        .get_sys_ticks = os_get_sys_ticks,
        .interrupt_save = _port_interrupt_save,
        .interrupt_restore = _port_interrupt_restore,
        .scheduler_disable = os_scheduler_suspend,
        .scheduler_enable = os_scheduler_resume,
        .get_work_q_hdl = _port_get_work_q_hdl,
        .thread_sleep = _port_thread_sleep,
    };
    k_init(&init_struct);

    os_work_q_create(default_os_work_q_hdl,
                     "app-work_q",
                     CONFIG_OS_THREAD_MAIN_STACK_SIZE,
                     CONFIG_OS_THREAD_MAIN_PRIORITY);

    static os_work_t _work_hdl_init;
    os_work_create(&_work_hdl_init, "work-main", work_route, NULL, 3);
    os_work_submit(default_os_work_q_hdl, &_work_hdl_init, 0);

    return 0;
}
