#include "StdAfx.h"
#include "DbLicServerFiller.h"
#define MODULO "DbLicServerFiller"
#include "_log.h"
#include "Licencia.h"
#include "CppSQLite3.h"
#define PATH_DB_LS "serverversionmanager.db"
#include <shlwapi.h>
#include <atltime.h>
DbLicServerFiller *DbLicServerFiller::_instance=NULL;

DbLicServerFiller::DbLicServerFiller(void)
{
}

DbLicServerFiller::~DbLicServerFiller(void)
{
}

DbLicServerFiller* DbLicServerFiller::Get()
{
	if(!_instance)
	{
		_instance = new DbLicServerFiller();
		if(!_instance->init())
			C_log::log(MODULO, "Error al inicializar db");
	}
	return _instance;
}

__int64 strToint64(const char* str)
{
	char st[32];
	int j =0;
	int state =0;//0 aņo, 1 mes 2 dia, 3 hora, 4 min, 5 seg
	int a=0,m=0,d=0,h =0,min=0,s=0, aux;
	for(int i =0; str[i]!=0 && state<6; i++)
	{
		if(str[i]== ':'|| str[i]== '-' || str[i]== ' ')
		{
			st[j]=0;
			j=0;
			aux = atoi(st);
			switch(state)
			{
			case(0):
				a =aux;
				break;
			case(1):
				m =aux;
				break;
			case(2):
				d =aux;
				break;
			case(3):
				h =aux;
				break;
			case(4):
				min =aux;
				break;
			case(5):
				s =aux;
				break;
			}
			state++;
			continue;
		}
		st[j++]=str[i];
	}
	
	CTime t = CTime(a,m,d,h,m,s);
	return t.GetTime();
}

bool DbLicServerFiller::fill( Licencia* lic )
{
	if(!db)
		return FALSE;
	std::string sql_select,caducidad;
	bool res = false;
	if(getProducId(lic)<0)
		return false;
	char s[32];
	sprintf(s,"%ld", lic->idProducto);
	sql_select = "SELECT * from licencias WHERE clave = \""+std::string(lic->clave)+"\" AND id_producto = "+std::string(s);

	CppSQLite3Query q = db->execQuery(sql_select.c_str());

	while (!q.eof() && !res)
	{

		lic->tipo = q.getIntField("tipo", 0);
		lic->instaId = q.getIntField("id_instalador", -1);
		lic->max_user = q.getIntField("user_max", 0);

		caducidad = q.getStringField("caducidad", "");
		lic->permisos = q.getIntField("permisos", 0);
		lic->renovacion = q.getIntField("renovacion", 0);
		lic->id = q.getIntField("id", -1);


		res =true;
		q.nextRow();
	}
	q.finalize();
	if(!res)
		return res;
	lic->caducidad = strToint64(caducidad.c_str());
	
	return res;
}

int DbLicServerFiller::getProducId( Licencia* lic )
{
	lic->idProducto = -1;
	if(!db)
		return lic->idProducto;
	std::string sql_select,caducidad;
	sql_select = "SELECT id from productos WHERE nombre = \""+std::string(lic->nombre_producto)+"\"";
	


	CppSQLite3Query q = db->execQuery(sql_select.c_str());

	while (!q.eof() && lic->idProducto<0)
	{
		lic->idProducto = q.getIntField("id", -1);
		q.nextRow();
	}
	q.finalize();
	return lic->idProducto;
}

bool DbLicServerFiller::init()
{
	if (!PathFileExists(PATH_DB_LS))
	{

		C_log::log(MODULO, "Error no se encuentra archivo db: %s",PATH_DB_LS );
		return false;
	}
	try
	{
		db = new CppSQLite3DB();
		db->open(PATH_DB_LS);
	}
	catch (CppSQLite3Exception ex)
	{
		C_log::log(MODULO, "Error al arbrir db: %s",PATH_DB_LS );
		return false;
	}
	return true;
}

int DbLicServerFiller::licCount( Licencia* lic )
{
	if(!db || lic->id<0)
		return -1;

	std::string sql_select,caducidad;
	//pilla usuario

	int  res = -1;
	int idusu = -1;
	CppSQLite3Query q;

	idusu =GetUsu(lic);
	

	if(idusu<0)
		return res;
	res =0;
	char ss[64];
	sprintf(ss,"%ld",lic->id);
	sql_select = "SELECT id_usu FROM acceso WHERE id_licencia = "+std::string(ss);
	q = db->execQuery(sql_select.c_str());
	while (!q.eof())
	{
		res++;
		if(idusu>=0 && idusu == q.getIntField("id_usu", -1))
		{
			res =0;
			q.finalize();
			return res;
		}
	}
	q.finalize();
	return res;
}
int DbLicServerFiller::GetUsu( Licencia* lic )
{
	if(!db)
		return -1;

	std::string sql_select,caducidad;
	//pilla usuario
	sql_select = "SELECT * from usuarios WHERE idm = \""+std::string(lic->idm)+"\"";
	int idusu = -1;

	CppSQLite3Query q = db->execQuery(sql_select.c_str());

	while (!q.eof() && idusu<0)
	{
		idusu= q.getIntField("id", -1);
		break;
	}
	q.finalize();

	if(idusu<0)
		idusu =SetUsu(lic );

	return idusu;
}

int DbLicServerFiller::SetUsu( Licencia* lic )
{
	if(!db || lic->instaId<=0)
		return FALSE;
	char ss[64];
	sprintf(ss,"%ld",lic->idCliente);
	std::string sql_select,caducidad;
	sql_select = "INSERT INTO usuarios (nombre, idm) "+
		std::string("VALUES (\"") +
		std::string(lic->nombre_user)+"\", \""+
		std::string(lic->idm)+"\");";
	bool res = false;
	int id_usu = -1;
	CppSQLite3Query q = db->execQuery(sql_select.c_str());
	res = q.eof();
	q.finalize();

	if(!res)
		return id_usu;
	res = false;
	sql_select = "SELECT id from usuarios WHERE idm = \""+std::string(lic->idm)+"\"";
	q = db->execQuery(sql_select.c_str());

	while (!q.eof() && !res)
	{
		id_usu = q.getIntField("id", -1);
		
		res =true;
		q.nextRow();
	}
	q.finalize();

	return id_usu;
}

bool DbLicServerFiller::fillInstal( Licencia* lic )
{
	if(!db || lic->instaId<=0)
		return FALSE;
	std::string sql_select,caducidad;
	char ss[64];
	sprintf(ss,"%ld",lic->instaId);
	sql_select = "SELECT * from instaladores WHERE id = "+std::string(ss);
	bool res = false;
	CppSQLite3Query q = db->execQuery(sql_select.c_str());

	while (!q.eof() && !res)
	{
		strcpy(lic->instaServer,q.getStringField("server", ""));
		strcpy(lic->instaKey,q.getStringField("clave", ""));
		strcpy(lic->instaUsu,q.getStringField("usuario", ""));

		strcpy(lic->instaDescrip,q.getStringField("archivo_descripcion", ""));
		strcpy(lic->instaPath,q.getStringField("archivo", ""));
		strcpy(lic->instaVersion,q.getStringField("version", ""));


		res =true;
		q.nextRow();
	}
	q.finalize();

	return res;
}

bool DbLicServerFiller::getConf( char *ip, int *port )
{
	if(!db)
		return FALSE;
	std::string sql_select,fuelstate,str,sql_where;

	sql_select = "SELECT * from configuracion_socket";
	bool res = false;

	CppSQLite3Query q = db->execQuery(sql_select.c_str());

	while (!q.eof() || !res)
	{

		*port = q.getIntField("puerto", -1);
		strcpy(ip, q.getStringField("ip", ""));
		res =true;
		q.nextRow();
	}
	q.finalize();
	return res;
}
bool DbLicServerFiller::setAcceso( Licencia* lic, __int64 *ultAcc,  __int64 *actualAcceso)
{
	int idusua = GetUsu(lic);
	if(!idusua)
		return false;
	//mira si existe
	std::string sql_select;
	char idusu[32];
	char idlic[32];
	char acces[32];
	CTime tiempo = CTime::GetCurrentTime();
	*actualAcceso=tiempo.GetTime();
	sprintf(acces,"%ld-%02d-%02d %02d:%02d %02d",
		tiempo.GetYear(), tiempo.GetMonth(), tiempo.GetDay(),
		tiempo.GetHour(), tiempo.GetMinute(), tiempo.GetSecond());
	sprintf(idusu, "%ld", idusua);
	sprintf(idlic, "%ld", lic->id);

	sql_select = "SELECT * from acceso WHERE id_licencia = "+std::string(idusu) +
		std::string(" AND id_usu = ")+std::string(idlic);

	bool res = false;
	CppSQLite3Query q = db->execQuery(sql_select.c_str());
	std::string ultimo_acceso;
	while (!q.eof() && !res)
	{
		ultimo_acceso = q.getStringField("ultimo_acceso", "");
		
		//falta pillar acceso y version si existe
		res =true;
		q.nextRow();
	}
	q.finalize();

	if(res)
	{
		*ultAcc = strToint64(ultimo_acceso.c_str());
		//update acceso
	
		sql_select = "UPDATE acceso "+
			std::string("SET ultimo_acceso = \"") + acces + std::string("\", version = \"")+
			lic->version_producto+ std::string("\" ")+
			"WHERE id_usu = "+std::string(idusu)+ " AND id_licencia = "+std::string(idlic)+";";
			q = db->execQuery(sql_select.c_str());
			res = q.eof();
			q.finalize();
			return res;
	}
	else
	{
		*ultAcc =0;
		//insert
		sql_select = "INSERT INTO acceso (id_usu, id_licencia, ultimo_acceso, version) "+
			std::string("VALUES( ")+
			std::string(idusu)+", "+
			std::string(idlic)+", \""+
			std::string(acces)+"\", \""+
			std::string(lic->version_producto)+"\");";
		q = db->execQuery(sql_select.c_str());
		res = q.eof();
		q.finalize();
		return res;

	}
	return false;
}
