/* Memory Debugging */
#ifdef DWC_DEBUG_MEMORY

#include "dwc_os.h"
#include "dwc_list.h"

struct allocation {
	void *addr;
	void *ctx;
	char *func;
	int line;
	uint32_t size;
	int dma;
	DWC_CIRCLEQ_ENTRY(allocation) entry;
};

DWC_CIRCLEQ_HEAD(allocation_queue, allocation);

struct allocation_manager {
	void *mem_ctx;
	struct allocation_queue allocations;

	/* statistics */
	int num;
	int num_freed;
	int num_active;
	uint32_t total;
	uint32_t cur;
	uint32_t max;
};

static struct allocation_manager *manager = NULL;

static int add_allocation(void *ctx, uint32_t size, char const *func, int line, void *addr,
			  int dma)
{
	struct allocation *a;

	DWC_ASSERT(manager != NULL, "manager not allocated");

	a = __DWC_ALLOC_ATOMIC(manager->mem_ctx, sizeof(*a));
	if (!a) {
		return -DWC_E_NO_MEMORY;
	}

	a->func = __DWC_ALLOC_ATOMIC(manager->mem_ctx, DWC_STRLEN(func) + 1);
	if (!a->func) {
		__DWC_FREE(manager->mem_ctx, a);
		return -DWC_E_NO_MEMORY;
	}

	DWC_MEMCPY(a->func, func, DWC_STRLEN(func) + 1);
	a->addr = addr;
	a->ctx = ctx;
	a->line = line;
	a->size = size;
	a->dma = dma;
	DWC_CIRCLEQ_INSERT_TAIL(&manager->allocations, a, entry);

	/* Update stats */
	manager->num++;
	manager->num_active++;
	manager->total += size;
	manager->cur += size;

	if (manager->max < manager->cur) {
		manager->max = manager->cur;
	}

	return 0;
}

static struct allocation *find_allocation(void *ctx, void *addr)
{
	struct allocation *a;

	DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) {
		if (a->ctx == ctx && a->addr == addr) {
			return a;
		}
	}

	return NULL;
}

static void free_allocation(void *ctx, void *addr, char const *func, int line)
{
	struct allocation *a = find_allocation(ctx, addr);

	if (!a) {
		DWC_ASSERT(0,
			   "Free of address %p that was never allocated or already freed %s:%d",
			   addr, func, line);
		return;
	}

	DWC_CIRCLEQ_REMOVE(&manager->allocations, a, entry);

	manager->num_active--;
	manager->num_freed++;
	manager->cur -= a->size;
	__DWC_FREE(manager->mem_ctx, a->func);
	__DWC_FREE(manager->mem_ctx, a);
}

int dwc_memory_debug_start(void *mem_ctx)
{
	DWC_ASSERT(manager == NULL, "Memory debugging has already started\n");

	if (manager) {
		return -DWC_E_BUSY;
	}

	manager = __DWC_ALLOC(mem_ctx, sizeof(*manager));
	if (!manager) {
		return -DWC_E_NO_MEMORY;
	}

	DWC_CIRCLEQ_INIT(&manager->allocations);
	manager->mem_ctx = mem_ctx;
	manager->num = 0;
	manager->num_freed = 0;
	manager->num_active = 0;
	manager->total = 0;
	manager->cur = 0;
	manager->max = 0;

	return 0;
}

void dwc_memory_debug_stop(void)
{
	struct allocation *a;

	dwc_memory_debug_report();

	DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) {
		DWC_ERROR("Memory leaked from %s:%d\n", a->func, a->line);
		free_allocation(a->ctx, a->addr, NULL, -1);
	}

	__DWC_FREE(manager->mem_ctx, manager);
}

void dwc_memory_debug_report(void)
{
	struct allocation *a;

	DWC_PRINTF("\n\n\n----------------- Memory Debugging Report -----------------\n\n");
	DWC_PRINTF("Num Allocations = %d\n", manager->num);
	DWC_PRINTF("Freed = %d\n", manager->num_freed);
	DWC_PRINTF("Active = %d\n", manager->num_active);
	DWC_PRINTF("Current Memory Used = %d\n", manager->cur);
	DWC_PRINTF("Total Memory Used = %d\n", manager->total);
	DWC_PRINTF("Maximum Memory Used at Once = %d\n", manager->max);
	DWC_PRINTF("Unfreed allocations:\n");

	DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) {
		DWC_PRINTF("    addr=%p, size=%d from %s:%d, DMA=%d\n",
			   a->addr, a->size, a->func, a->line, a->dma);
	}
}

/* The replacement functions */
void *dwc_alloc_debug(void *mem_ctx, uint32_t size, char const *func, int line)
{
	void *addr = __DWC_ALLOC(mem_ctx, size);

	if (!addr) {
		return NULL;
	}

	if (add_allocation(mem_ctx, size, func, line, addr, 0)) {
		__DWC_FREE(mem_ctx, addr);
		return NULL;
	}

	return addr;
}

void *dwc_alloc_atomic_debug(void *mem_ctx, uint32_t size, char const *func,
			     int line)
{
	void *addr = __DWC_ALLOC_ATOMIC(mem_ctx, size);

	if (!addr) {
		return NULL;
	}

	if (add_allocation(mem_ctx, size, func, line, addr, 0)) {
		__DWC_FREE(mem_ctx, addr);
		return NULL;
	}

	return addr;
}

void dwc_free_debug(void *mem_ctx, void *addr, char const *func, int line)
{
	free_allocation(mem_ctx, addr, func, line);
	__DWC_FREE(mem_ctx, addr);
}

void *dwc_dma_alloc_debug(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr,
			  char const *func, int line)
{
	void *addr = __DWC_DMA_ALLOC(dma_ctx, size, dma_addr);

	if (!addr) {
		return NULL;
	}

	if (add_allocation(dma_ctx, size, func, line, addr, 1)) {
		__DWC_DMA_FREE(dma_ctx, size, addr, *dma_addr);
		return NULL;
	}

	return addr;
}

void *dwc_dma_alloc_atomic_debug(void *dma_ctx, uint32_t size,
				 dwc_dma_t *dma_addr, char const *func, int line)
{
	void *addr = __DWC_DMA_ALLOC_ATOMIC(dma_ctx, size, dma_addr);

	if (!addr) {
		return NULL;
	}

	if (add_allocation(dma_ctx, size, func, line, addr, 1)) {
		__DWC_DMA_FREE(dma_ctx, size, addr, *dma_addr);
		return NULL;
	}

	return addr;
}

void dwc_dma_free_debug(void *dma_ctx, uint32_t size, void *virt_addr,
			dwc_dma_t dma_addr, char const *func, int line)
{
	free_allocation(dma_ctx, virt_addr, func, line);
	__DWC_DMA_FREE(dma_ctx, size, virt_addr, dma_addr);
}

#endif /* DWC_DEBUG_MEMORY */
