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

#include <zephyr/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;

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

	if (k_is_in_isr()) {
		return osErrorISR;
	}

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

	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)));
}
