/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <kernel.h>
#include <string.h>
#include "wrapper.h"

#define ACTIVE 1
#define NOT_ACTIVE 0

static void zephyr_timer_wrapper(struct k_timer *timer);

K_MEM_SLAB_DEFINE(cv2_timer_slab, sizeof(struct cv2_timer),
		  CONFIG_CMSIS_V2_TIMER_MAX_COUNT, 4);

static const osTimerAttr_t init_timer_attrs = {
	.name = "ZephyrTimer",
	.attr_bits = 0,
	.cb_mem = NULL,
	.cb_size = 0,
};

static void zephyr_timer_wrapper(struct k_timer *timer)
{
	struct cv2_timer *cm_timer;

	cm_timer = CONTAINER_OF(timer, struct cv2_timer, z_timer);
	(cm_timer->callback_function)(cm_timer->arg);
}

/**
 * @brief Create a Timer
 */
osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type,
		       void *argument, const osTimerAttr_t *attr)
{
	struct cv2_timer *timer;

	if (type != osTimerOnce && type != osTimerPeriodic) {
		return NULL;
	}

	if (k_is_in_isr()) {
		return NULL;
	}

	if (attr == NULL) {
		attr = &init_timer_attrs;
	}

	if (k_mem_slab_alloc(&cv2_timer_slab, (void **)&timer, K_MSEC(100)) == 0) {
		(void)memset(timer, 0, sizeof(struct cv2_timer));
	} else {
		return NULL;
	}

	timer->callback_function = func;
	timer->arg = argument;
	timer->type = type;
	timer->status = NOT_ACTIVE;

	k_timer_init(&timer->z_timer, zephyr_timer_wrapper, NULL);

	if (attr->name == NULL) {
		strncpy(timer->name, init_timer_attrs.name,
			sizeof(timer->name) - 1);
	} else {
		strncpy(timer->name, attr->name, sizeof(timer->name) - 1);
	}

	return (osTimerId_t)timer;
}

/**
 * @brief Start or restart a Timer
 */
osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks)
{
	struct cv2_timer *timer = (struct cv2_timer *)timer_id;
	u32_t millisec = k_ticks_to_ms_floor64(ticks);

	if (timer == NULL) {
		return osErrorParameter;
	}

	if (k_is_in_isr()) {
		return osErrorISR;
	}

	if (timer->type == osTimerOnce) {
		k_timer_start(&timer->z_timer, millisec, K_NO_WAIT);
	} else if (timer->type == osTimerPeriodic) {
		k_timer_start(&timer->z_timer, K_NO_WAIT, millisec);
	}

	timer->status = ACTIVE;
	return osOK;
}

/**
 * @brief Stop the Timer
 */
osStatus_t osTimerStop(osTimerId_t timer_id)
{
	struct cv2_timer *timer = (struct cv2_timer *)timer_id;

	if (timer == NULL) {
		return osErrorParameter;
	}

	if (k_is_in_isr()) {
		return osErrorISR;
	}

	if (timer->status == NOT_ACTIVE) {
		return osErrorResource;
	}

	k_timer_stop(&timer->z_timer);
	timer->status = NOT_ACTIVE;
	return osOK;
}

/**
 * @brief Delete the timer that was created by osTimerCreate
 */
osStatus_t osTimerDelete(osTimerId_t timer_id)
{
	struct cv2_timer *timer = (struct cv2_timer *) timer_id;

	if (timer == NULL) {
		return osErrorParameter;
	}

	if (k_is_in_isr()) {
		return osErrorISR;
	}

	if (timer->status == ACTIVE) {
		k_timer_stop(&timer->z_timer);
		timer->status = NOT_ACTIVE;
	}

	k_mem_slab_free(&cv2_timer_slab, (void *) &timer);
	return osOK;
}

/**
 * @brief Get name of a timer.
 */
const char *osTimerGetName(osTimerId_t timer_id)
{
	struct cv2_timer *timer = (struct cv2_timer *)timer_id;

	if (k_is_in_isr() || (timer == NULL)) {
		return NULL;
	}

	return timer->name;
}

/**
 * @brief Check if a timer is running.
 */
uint32_t osTimerIsRunning(osTimerId_t timer_id)
{
	struct cv2_timer *timer = (struct cv2_timer *)timer_id;

	if (k_is_in_isr() || (timer == NULL)) {
		return 0;
	}

	return !(!(k_timer_remaining_get(&timer->z_timer)));
}
