#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "drLog.h"
#include <dashboard.h>
#include "drTimaMm.h"
#if TBASE_API_LEVEL >= 5
#include "DrApi/DrApiMmExt.h"
extern addr_t tima_dashboard_va;
#endif

char *sec_log_strings[] = {
	"Dashboard Header",	/* HEADER */
	"Kernel verification failure",	/* KERN_HASH_MISMATCH */
	"kern_sec_info signature verification failure",	/* KERN_METADATA_ERR */
	"SELinux verification failure",	/* SELINUX_OFF */
	"Module Hash value not match",	/* LKM_HASH_MISMATCH */
	"Internal Error",	/* GENERIC */
};

void dashboard_init(
	void
)
{
#if TBASE_API_LEVEL >= 5
	dashboard_row_t *ptr = (dashboard_row_t *) (uint32_t *)tima_dashboard_va;
#else
	dashboard_row_t *ptr = (dashboard_row_t *) TIMA_DASHBOARD_VADDR;
#endif
	int i;

	/* ptr initialyy points to the header */
	if (ptr->type != MAGIC) {	/* Magic */
		ptr->type = MAGIC;
		ptr->nr_occurences = 0;
		ptr->timestamp = 0;
		ptr++;

		/* Fill-up all entries now */
		for (i = 1; i <= GENERIC; i++) {
			ptr->type = (sec_entry_t) i;
			ptr->nr_occurences = 0;
			ptr->timestamp = 0;
			ptr++;
		}
	}

}

void dashboard_read_entry(
	sec_entry_t entry_type,
	dashboard_row_t * entry
)
{
#if TBASE_API_LEVEL >= 5
	dashboard_row_t *ptr = (dashboard_row_t *) (uint32_t *)tima_dashboard_va;
#else
	dashboard_row_t *ptr = (dashboard_row_t *) TIMA_DASHBOARD_VADDR;
#endif
	if (entry_type > GENERIC) {
		memset(entry, 0, sizeof(dashboard_row_t));
		return;
	}

	memcpy(entry, ptr + entry_type, sizeof(dashboard_row_t));
}

void dashboard_read_all(
	dashboard_row_t * entry
)
{
#if TBASE_API_LEVEL >= 5
	dashboard_row_t *ptr = (dashboard_row_t *) (uint32_t *)tima_dashboard_va;
#else
	dashboard_row_t *ptr = (dashboard_row_t *) TIMA_DASHBOARD_VADDR;
#endif
	memcpy(entry, ptr, sizeof(dashboard_row_t) * DASHBOARD_MAX_ENTRIES);
}

void dashboard_update(
	sec_entry_t entry_type
)
{
#if TBASE_API_LEVEL >= 5
	dashboard_row_t *ptr = (dashboard_row_t *) (uint32_t *)tima_dashboard_va;
#else
	dashboard_row_t *ptr = (dashboard_row_t *) TIMA_DASHBOARD_VADDR;
#endif	
	if (entry_type > GENERIC)
		/* GENERIC is always the last error type. 
		 * Anything greater than GENERIC is outside the dashboard.
		 */
		return;

	ptr += (uint32_t) entry_type;
	ptr->nr_occurences++;
	ptr->timestamp = get_time();
}

char *dashboard_lookup_msg_type(
	sec_entry_t entry_type
)
{
	if (entry_type > GENERIC)
		entry_type = GENERIC;

	return sec_log_strings[entry_type];
}

void dashboard_dump(
	void
)
{
	unsigned int i;
#if TBASE_API_LEVEL >= 5
	dashboard_row_t *ptr = (dashboard_row_t *) (uint32_t *)tima_dashboard_va;
#else
	dashboard_row_t *ptr = (dashboard_row_t *) TIMA_DASHBOARD_VADDR;
#endif
	for (i = 0; i <= GENERIC; i++) {
		DEBUG_LOG("Entry 0x%x: NR_OCCURENCE:%u, TIMESTAMP:%lld",
			  ptr->type, ptr->nr_occurences, ptr->timestamp);
		ptr++;
	}
}
