/*
 * Copyright (c) 2022-2023, Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Arm SiP services service ID manager and ID mapping table force
 * clients and transactions.
 */

#include <zephyr/kernel.h>
#include <zephyr/drivers/sip_svc/sip_svc_proto.h>
#include "sip_svc_id_mgr.h"

/**
 * Create a id key pool using size variable  0..size-1, where we can
 * track the allocated id.
 */
struct sip_svc_id_pool *sip_svc_id_mgr_create(uint32_t size)
{
	struct sip_svc_id_pool *id_pool = NULL;
	uint32_t mask_size = 0;
	uint32_t i = 0;

	if (size == SIP_SVC_ID_INVALID) {
		return NULL;
	}

	/* Allocate memory for ID pool */
	id_pool = k_malloc(sizeof(struct sip_svc_id_pool));
	if (!id_pool) {
		return NULL;
	}
	id_pool->size = size;

	id_pool->id_list = k_malloc(size * sizeof(uint32_t));
	if (!id_pool->id_list) {
		k_free(id_pool);
		return NULL;
	}

	mask_size = size / sizeof(uint32_t);
	if (size % sizeof(uint32_t)) {
		mask_size++;
	}

	id_pool->id_mask = k_malloc(mask_size * sizeof(uint32_t));
	if (!id_pool->id_mask) {
		k_free(id_pool->id_list);
		k_free(id_pool);
		return NULL;
	}

	/* Initialize ID */
	for (i = 0; i < size; i++) {
		id_pool->id_list[i] = i;
	}

	/* ID pool is full during initialization */
	id_pool->head = 0;
	id_pool->tail = size - 1;

	/* Initialize ID in use flags */
	for (i = 0; i < mask_size; i++) {
		id_pool->id_mask[i] = 0;
	}

	return id_pool;
}

/* Delete a created id pool*/
void sip_svc_id_mgr_delete(struct sip_svc_id_pool *id_pool)
{
	if (id_pool) {
		k_free(id_pool->id_mask);
		k_free(id_pool->id_list);
		k_free(id_pool);
	}
}

/* Retrieve an id from the id pool*/
uint32_t sip_svc_id_mgr_alloc(struct sip_svc_id_pool *id_pool)
{
	uint32_t id;
	uint32_t row;
	uint32_t col;

	if (!id_pool) {
		return SIP_SVC_ID_INVALID;
	}

	if (id_pool->head == SIP_SVC_ID_INVALID) {
		return SIP_SVC_ID_INVALID;
	}

	id = id_pool->id_list[id_pool->head];

	/* Calculate the mask bit position in id mask array*/
	row = id / sizeof(uint32_t);
	col = id % sizeof(uint32_t);
	id_pool->id_mask[row] |= (1 << col);

	if (id_pool->head == id_pool->tail) {
		id_pool->head = SIP_SVC_ID_INVALID;
		id_pool->tail = SIP_SVC_ID_INVALID;
	} else {
		id_pool->head++;
		if (id_pool->head == id_pool->size) {
			id_pool->head = 0;
		}
	}

	return id;
}

/* Free the id that was allocated from the id_pool*/
void sip_svc_id_mgr_free(struct sip_svc_id_pool *id_pool, uint32_t id)
{
	uint32_t row;
	uint32_t col;

	if (!id_pool) {
		return;
	}

	if (id >= id_pool->size) {
		return;
	}

	row = id / sizeof(uint32_t);
	col = id % sizeof(uint32_t);

	/* check if the id was allocated earlier*/
	if (!(id_pool->id_mask[row] & (1 << col))) {
		return;
	}

	/* Clear the id mask bit */
	id_pool->id_mask[row] &= ~(1 << col);

	if (id_pool->head == SIP_SVC_ID_INVALID) {
		id_pool->head = 0;
		id_pool->tail = 0;
	} else {
		id_pool->tail++;
		if (id_pool->tail == id_pool->size) {
			id_pool->tail = 0;
		}
		if (id_pool->head == id_pool->tail) {
			return;
		}
	}

	id_pool->id_list[id_pool->tail] = id;
}

/* Allocate database to store values */
struct sip_svc_id_map *sip_svc_id_map_create(uint32_t size)
{
	struct sip_svc_id_map *id_map = NULL;
	uint32_t items_size = (sizeof(struct sip_svc_id_map_item)) * size;
	int i;

	id_map = k_malloc(sizeof(struct sip_svc_id_map));
	if (!id_map) {
		return NULL;
	}

	id_map->items = k_malloc(items_size);
	if (!id_map->items) {
		k_free(id_map);
		return NULL;
	}

	id_map->size = size;
	for (i = 0; i < size; i++) {
		id_map->items[i].id = SIP_SVC_ID_INVALID;
		id_map->items[i].arg1 = NULL;
		id_map->items[i].arg2 = NULL;
		id_map->items[i].arg3 = NULL;
		id_map->items[i].arg4 = NULL;
		id_map->items[i].arg5 = NULL;
		id_map->items[i].arg6 = NULL;
	}

	return id_map;
}


/* Delete a created database */
void sip_svc_id_map_delete(struct sip_svc_id_map *id_map)
{
	if (id_map) {
		k_free(id_map->items);
		k_free(id_map);
	}
}

/* Retrieve index from from database with key(id)*/
static int sip_svc_id_map_get_idx(struct sip_svc_id_map *id_map, uint32_t id)
{
	int i;

	if (!id_map) {
		return -EINVAL;
	}

	for (i = 0; i < id_map->size; i++) {
		if (id_map->items[i].id == id) {
			return i;
		}
	}

	return -EINVAL;
}

/* Insert an entry into database with key as id*/
int sip_svc_id_map_insert_item(struct sip_svc_id_map *id_map, uint32_t id, void *arg1, void *arg2,
			       void *arg3, void *arg4, void *arg5, void *arg6)
{
	int i;

	if (!id_map) {
		return -EINVAL;
	}

	i = sip_svc_id_map_get_idx(id_map, SIP_SVC_ID_INVALID);
	if (i < 0) {
		return -EINVAL;
	}

	id_map->items[i].id = id;
	id_map->items[i].arg1 = arg1;
	id_map->items[i].arg2 = arg2;
	id_map->items[i].arg3 = arg3;
	id_map->items[i].arg4 = arg4;
	id_map->items[i].arg5 = arg5;
	id_map->items[i].arg6 = arg6;

	return 0;
}

/* Remove an entry with key id */
int sip_svc_id_map_remove_item(struct sip_svc_id_map *id_map, uint32_t id)
{
	int i;

	if (!id_map) {
		return -EINVAL;
	}

	i = sip_svc_id_map_get_idx(id_map, id);
	if (i < 0) {
		return -EINVAL;
	}

	id_map->items[i].id = SIP_SVC_ID_INVALID;
	id_map->items[i].arg1 = NULL;
	id_map->items[i].arg2 = NULL;
	id_map->items[i].arg3 = NULL;
	id_map->items[i].arg4 = NULL;
	id_map->items[i].arg5 = NULL;
	id_map->items[i].arg6 = NULL;

	return 0;
}

/* Query an entry from database using key id*/
struct sip_svc_id_map_item *sip_svc_id_map_query_item(struct sip_svc_id_map *id_map, uint32_t id)
{
	int i;

	if (!id_map) {
		return NULL;
	}

	i = sip_svc_id_map_get_idx(id_map, id);
	if (i < 0) {
		return NULL;
	}

	return &id_map->items[i];
}
