/*
   core/uid.cc
   This file is part of the Osirion project and is distributed under
   the terms of the GNU General Public License version 2.
*/ 

// #include <cstring>
#include "sys/sys.h"
#include "core/uid.h"
#include "math/functions.h"

#include <cstring>

namespace core
{

const char hexchar[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

UID::UID()
{
	clear();
}

UID::~UID()
{
	clear();
}

UID::UID(const UID & other)
{
	assign(other);
}

void UID::assign(const UID & other)
{
	memcpy(uid_key, other.uid_key, UIDKEYSIZE);
}

void UID::assign(const std::string & str)
{
	char new_key[UIDKEYSIZE];
	char l, h;
	
	if (str.size() != UIDKEYSIZE * 2) {
		return;
	}
	
	for (size_t i = 0; i < UIDKEYSIZE; i++ ) {
		h = str[i * 2];
		switch (h) {
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				new_key[i] = (h - '0') << 4;
				break;
			case 'a':
			case 'b':
			case 'c':
			case 'd':
			case 'e':
			case 'f':
				new_key[i] = (h - 'a' + 10) << 4;
				break;
			default:
				return;
				break;
		}
		
		l = str[i * 2 + 1];
		switch (l) {
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				new_key[i] += (l - '0');
				break;
			case 'a':
			case 'b':
			case 'c':
			case 'd':
			case 'e':
			case 'f':
				new_key[i] += (l - 'a' + 10);
				break;
			default:
				return;
				break;
		}
	}
	
	memcpy(uid_key, new_key, UIDKEYSIZE);
}

void UID::generate()
{
	for (size_t i = 0; i < UIDKEYSIZE; i++) {
		// FIXME the worst random key generator ever
		uid_key[i] = math::randomi(256);
	}
}

bool UID::is_valid() const
{
	for (size_t i = 0; i < UIDKEYSIZE; i++) {
		if (uid_key[i] != 0 )
			return true;
	}
	return false;
}

void UID::clear()
{
	memset(uid_key, 0, UIDKEYSIZE);
}

const std::string UID::str() const {
	std::string s;
	for (size_t i = 0; i < UIDKEYSIZE; i++) {
		// upper nibble
		s += hexchar[ uid_key[i] >> 4 ];
		// lower nibble
		s += hexchar[ uid_key[i] % 16 ];
	}
	return s;
}


} // namespace core