/* =================================================================== *
 * Вариант реализации функции генерации уникального идентификатора     *
 * договора (сделки)  в соответствии с указанием Банка России          *
 * "О правилах присвоения уникального идентификатора договора (сделки),*
 * по обязательствам из которого (из которой) формируется кредитная    *
 * история"                                                            *
 * =================================================================== */


#include <stdio.h>
#include "uid.h"
#include "uuid.h"

//Инициализация модуля
bool uid_init(void)
{
	return uuid_init();
}

//Деинициализация модуля (освобождение ресурсов)
void uid_deinit(void)
{
	uuid_deinit();
}

//Расчет контрольного символа
//str - указатель на строку, содержащую первую часть УИД.
char calc_ctrl(char *str)
{
	int pos = 0;   //позиция символа первой части УИД
	int index = 1; //индекс цифры первой части УИД
	long sum = 0;  //сумма произведений цифр и их индексов
	
	//цикл по строке до достижения конца строки
	while(str[pos]){
		//получение очередного символа строки
	    char c=str[pos++];	
	    
	    //если символ - десятичная цифра
		if(c>='0' && c<='9'){
			//увеличение суммы и индекса
			sum+=(c-'0')*(index++);
		}
		
		//если символ - шестнадцатеричная цифра
		if(c>='a' && c<='f'){
			//увеличение суммы и индекса
			sum+=(c-'a'+10)*(index++);
		}
		
		//если значение индекса превысило 10, сбрасываем индекс в 1
		if(index>10) index=1;
	}
	
	//получение остатка от деления суммы произведений цифр с их индексом на 16
	int r = sum % 16;
	
	//возврат результата в виде контрольного символа
	if(r<10){
		return (char)(r+'0');
	} else {
		return (char)(r+'a'-10);
	}		
}

//Создание УИД
//buffer - указатель на буфер длиной не менее 39 байт (38 байт УИД и 1 байт символ конца строки)
//Возвращаемый результат:
//  true - если УИД создан успешно и помещен в буфер
//  false - если УИД создать не удалось
bool uid_create(char *buffer)
{
	uuid_t uuid;
	//Создание первой части УИД - УУИд
	//Если УУИД создать не удалось, возвращаем отрицательный результат
	if(!uuid_create(&uuid)) return false;
	
	//Преобразуем созданный УУИд в шестнадцатеричное представление
	sprintf(buffer,"%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x-",
					uuid.time_low, 
					uuid.time_mid,
					uuid.time_hi_and_version,
					uuid.clock_seq_hi_and_reserved,
					uuid.clock_seq_low,
					uuid.node[5],uuid.node[4],uuid.node[3],uuid.node[2],uuid.node[1],uuid.node[0]);	

    //расчет и помещение в буфер контрольного символа					
	buffer[UID_BUFFER_SIZE-2]=calc_ctrl(buffer);	
	//помещение в буфер символа конца строки			
	buffer[UID_BUFFER_SIZE-1]=0;
	
	return true;
}

