/**
* \file log.c
* \brief Logging functions.
* \author Sergey Tolochko (s.tolochko@samsung.com)
* \version 0.1
* \date Created Feb 11, 2016
* \par In Samsung Ukraine R&D Center (SURC) under a contract between
* \par LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine) and
* \par "Samsung Elecrtronics Co", Ltd (Seoul, Republic of Korea)
* \par Copyright: (c) Samsung Electronics Co, Ltd 2012. All rights reserved.
**/
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include "commonConfig.h"
#include "CommLayerData.h"
#include "log.h"

#ifndef DISABLE_LOG_ENCRYPTION
#include "circularQueue.h"
#endif  // End of DISABLE_LOG_ENCRYPTION

#define PRINT_LEN 1024
#define FILE_LEN 18

#if (defined USE_BLOWFISH)
char * __attribute__((weak)) strrchr(const char *str, int c)
{
	char *p = NULL;

	if(str == NULL)
		return NULL;

	p = (char *)str + strlen(str) - 1;

	while(*p != '\0' && p > str)
	{   
		if(*p == c)
			return p;
		p--;
	}   
	return NULL;
}
#endif	// End of USE_BLOWFISH

int32_t log_print(const char* tag, const char* file, uint32_t line,
                const char* format, ...)
{
	va_list args;
	int32_t len = 0;
	char buffer[PRINT_LEN] = {0};
	const char *pFile = NULL;

	if(tag == NULL || file == NULL || format == NULL)
	{
		TEE_LOG("%s : Invalid argument.", __func__);
		return ERR_TA_INVALID_ARGUMENT;
	}

	memset(buffer, 0, sizeof(buffer));

	if((pFile = strrchr(file, '/')) != NULL)
		pFile++;
	else
		pFile = file;

	len = snprintf(buffer, PRINT_LEN, "%s %-*s:%4d: ", tag, FILE_LEN, pFile, (int32_t)line);

	if (len < 0)
	{
		TEE_LOG("Failed to print buffer with error %d.", len);
		return ERR_TA_BUFFER_OVERFLOW;
	}

	va_start (args, format);
	vsnprintf(buffer + len, ARRAY_SIZE(buffer) - len, format, args);
	va_end (args);

#ifndef DISABLE_LOG_ENCRYPTION
	enqueueData(buffer, strlen(buffer));
#endif // End of DISABLE_LOG_ENCRYPTION
	TEE_PLATFORM_PRINT(buffer);
	return NOT_ERROR;
}

#ifdef DEBUG
void log_mem_dump( const char *message, const void *pdata, size_t data_size )
{
	char out[512] = {0};
	size_t i;
	int pos = 0;
	unsigned char *data = (unsigned char*)pdata;
	static const char hexes[] = "0123456789ABCDEF";

	TEE_LOG( "===== Memory dump START --> '%s', size = %d ======", message, data_size);

	for( i = 0; i < data_size; ++i )
	{
		out[pos++] = hexes[data[i] >> 4];
		out[pos++] = hexes[data[i] & 0xF];
		out[pos++] = ' ';
		if ((i+1) % 32 == 0)
		{
			TEE_LOG( "%s", out );
			pos = 0;
		}
	}
	out[pos] = 0;
	TEE_LOG( "%s", out );
	TEE_LOG( "===== Memory dump END --> '%s' ======", message);
}
#endif
