/*
 * Copyright (C) 2009 - 2010 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */


#include "Logger/LoggerMacroses.h"
#include "Utils.h"


#define NONCE_LENGTH	7
const char NonceChars[] = "ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";


namespace NS_DM_Client
{


Funambol::NextNonce * CreateNonce()
{
	char nonce[NONCE_LENGTH] = { 0 };
	int count = sizeof(NonceChars)/sizeof(char);
	for (int i=0; i<NONCE_LENGTH; ++i)
		nonce[i] = NonceChars[rand() % count];
	
	return new Funambol::NextNonce(nonce, NONCE_LENGTH);
}
	
	
bool IsBooleanTrue(String &value)
{
	return	!value.compare("true")		|| 
			!value.compare("TRUE")		|| 
			!value.compare("true\n")	|| 
			!value.compare("TRUE\n")	||
			!value.compare("1")			|| 
			!value.compare("1\n");
}


void PrintMessage(const char * logger, const char * prefix, const char * msg)
{
	GLDEBUG(logger, "print message, size is %d [%p]", msg ? strlen(msg) : 0, msg);
	// the aim of this routine is to find and shorten possibly too large Data section
	char * message = NULL;
	if (msg && msg[0])
	{
		message = Funambol::stringdup(msg);
	}
	
	// delete all Data sections larger than 64 bytes
	const char * datab = "<Data>";
	const char * datae = "</Data>";
	
	if (message && message[0])
	{
		char * pDataB = message;
		char * pDataE = NULL;
		do
		{
			pDataB = strstr(pDataB, datab);
///			GLDEBUG(logger, "sdsdsd     %s", pDataB);
			if (pDataB)
			{
				pDataB += strlen(datab);
				pDataE = strstr(pDataB, datae);
				
				int datasize = pDataE - pDataB;
				const char * expand_pattern = "[..., %d bytes data section]";
				if (datasize > (int)(64 + strlen(expand_pattern) + 16))
				{
					char sizestr[128] = {0};
					__sprintf(sizestr, expand_pattern, datasize);
					
					char * tail = new char[strlen(message)];
					memset(tail, 0, strlen(message));
					__strcpy(tail, pDataE);
					
					__strcpy(pDataB+64, sizestr);
					__strcpy(pDataB+64+strlen(sizestr), tail);
					
					pDataB = pDataB+64+strlen(sizestr)+strlen(pDataE);
					SAFE_DELETE_ARR(tail);
				}
			}
		}
		while(pDataB);
	}
	
	GLDEBUG(logger, "%s [%d bytes]\n\n%s\n", prefix, msg ? strlen(msg) : 0, message ? message : "NULL");
	SAFE_DELETE_ARR(message);	
}


String ToString(int value)
{
	const int maxSize = 1024;
	char buffer[maxSize] = {0};
	__sprintf(buffer, "%i", value);
	//_itoa(value, buffer, 10);
	return buffer;
}

static inline char* char2hex(char c, char* buf)
{
	static const char bits2char[] = "0123456789ABCDEF";
	buf[0] = bits2char [((unsigned char)c) >> 4];
	buf[1] = bits2char [((unsigned char)c) & 0xF];
	buf[2] = 0;
	return buf;
}


const char* Utils::ToAsciiHex(String& dest, const void* data, size_t dataSize, char byteSeparator)
{
	const size_t byte2asciiSize = 2;
	const size_t reserveSize = dataSize * (byte2asciiSize + (byteSeparator == 0) ? 0 : 1);

	dest.clear();
	dest.reserve(reserveSize);

	char separ[2];
	separ[0] = byteSeparator;
	separ[1] = 0;

	char buf[4];
	const char* ptr = static_cast<const char*>(data);
	while (dataSize--)
	{
		dest += char2hex(*ptr++, buf);
		dest += separ;
	}

	return dest.c_str();
}


}
