#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "nrtrde.h"

seq_buffer seq_buf;

int add_seq_obj(seq_buffer *seq_buf,seq_object *add_obj);
unsigned long find_seq_obj(seq_buffer *seq_buf,char *keyvalue);
int get_seq_num(char *tadig,int type,char *out_seq);
int init_seq();
int store_seq();


int add_seq_obj(seq_buffer *seq_buf,seq_object *add_obj)
{
	int unitlen;
	int low,high,mid,last;
	char tmpvalue[24];
	char keyfield[24];
	seq_object tmp_seq_obj_list[HPMN_SERVER_COUNT];
	
	if(seq_buf->count >= HPMN_SERVER_COUNT)
		return 0;
		
	unitlen=sizeof(seq_object);
	mid=0;
	low=0;
	high=seq_buf->count-1;
	
	memset(keyfield,0,sizeof(keyfield));
	sprintf(keyfield,"%s",add_obj->tadig);
	
	memset(tmpvalue,0,sizeof(tmpvalue));
	memcpy(tmpvalue,seq_buf->seq_obj[high].tadig,8);
	if(strcmp(keyfield,tmpvalue) == 0)
	{
		return 0;
	}
	else if(strcmp(keyfield,tmpvalue) > 0)
	{
		sprintf(seq_buf->seq_obj[seq_buf->count].tadig,"%s",keyfield);
		seq_buf->seq_obj[seq_buf->count].nr_seq_num=add_obj->nr_seq_num;
		seq_buf->seq_obj[seq_buf->count].nd_seq_num=add_obj->nd_seq_num;
		seq_buf->seq_obj[seq_buf->count].ne_seq_num=add_obj->ne_seq_num;
	}
	else
	{	
	  while(low <= high)
	  {
	  	mid=(low+high)/2;
	  	memset(tmpvalue,0,sizeof(tmpvalue));
			memcpy(tmpvalue,seq_buf->seq_obj[mid].tadig,8);
		  if(strcmp(keyfield,tmpvalue) == 0)   
		  	return 0; 
	  	else if(strcmp(keyfield,tmpvalue) < 0)   
	  		high=mid-1;
			else   
				low=mid+1;
	  }
		if(low > high)
			last=low;
		else
			last=mid;

		memcpy(tmp_seq_obj_list,seq_buf->seq_obj,sizeof(tmp_seq_obj_list));
		
		memcpy(&seq_buf->seq_obj[last+1],&tmp_seq_obj_list[last],(HPMN_SERVER_COUNT-last-1)*unitlen);
		sprintf(seq_buf->seq_obj[last].tadig,"%s",keyfield);
		seq_buf->seq_obj[last].nr_seq_num=add_obj->nr_seq_num;
		seq_buf->seq_obj[last].nd_seq_num=add_obj->nd_seq_num;
		seq_buf->seq_obj[last].ne_seq_num=add_obj->ne_seq_num;
	}
	seq_buf->count++;
	return 1;
}

/*
return NO_FIND:can not find
*/
unsigned long find_seq_obj(seq_buffer *seq_buf,char *keyvalue)
{
	char tmpvalue[24];
	char keyfield[24];
	int low,high,mid;
	
	mid=0;
	low=0;
	high=seq_buf->count-1;
	
	memset(keyfield,0,sizeof(keyfield));
	sprintf(keyfield,"%s",keyvalue);
	
	memset(tmpvalue,0,sizeof(tmpvalue));
	memcpy(tmpvalue,seq_buf->seq_obj[high].tadig,8);
	if(strcmp(keyfield,tmpvalue) == 0)
		return high;
	else if(strcmp(keyfield,tmpvalue) > 0)
		return NO_FIND;
	else
	{	
	  while(low <= high)
	  {
	  	mid=(low+high)/2;
	  	memset(tmpvalue,0,sizeof(tmpvalue));
			memcpy(tmpvalue,seq_buf->seq_obj[mid].tadig,8);
		  if(strcmp(keyfield,tmpvalue) == 0)   
		  	return mid; 
	  	else if(strcmp(keyfield,tmpvalue) < 0)   
	  		high=mid-1;
			else   
				low=mid+1;
	  }
	}
	
	return NO_FIND;
}

int init_seq()
{
	FILE *handle=NULL;
	memset(&seq_buf,0,sizeof(seq_buf));
	handle=fopen(SEQ_NUM_CONF,"r+");
	if(handle == NULL)
	{
		FILE *tmpf;
		tmpf=fopen(SEQ_NUM_CONF,"w+");
		if(tmpf == NULL)
		{
			printf("Can not create the %s\n",SEQ_NUM_CONF);
			exit(0);
		}
		fwrite(&seq_buf,sizeof(seq_buf),1,tmpf);
		fclose(tmpf);
		handle=fopen(SEQ_NUM_CONF,"r+");
	}
	fread(&seq_buf,sizeof(seq_buf),1,handle);
	printf("Load sequence number conf from %s\n",SEQ_NUM_CONF);
	fclose(handle);
	
	return 1;
}

int store_seq()
{
	FILE *handle=NULL;
	
	handle=fopen(SEQ_NUM_CONF,"w+");
	if(handle == NULL)
	{
		printf("Can not write the %s\n",SEQ_NUM_CONF);
		exit(0);
	}
	
	fwrite(&seq_buf,sizeof(seq_buf),1,handle);
	fclose(handle);
	
	return 1;
}

//type:0-NR, 1-ND, 2-NE;
int get_seq_num(char *tadig,int type,char *out_seq)
{
	unsigned long find_index;
	
	find_index=find_seq_obj(&seq_buf,tadig);
	if(find_index == NO_FIND)
	{
		if(type == 0)
			sprintf(out_seq,"0000001");
		else
			sprintf(out_seq,"00001");
		return 0;
	}
	
	if(type == 0)
	{
		if(seq_buf.seq_obj[find_index].nr_seq_num == 0)
			seq_buf.seq_obj[find_index].nr_seq_num++;
		sprintf(out_seq,"%07ld",seq_buf.seq_obj[find_index].nr_seq_num);
		seq_buf.seq_obj[find_index].nr_seq_num++;
		seq_buf.seq_obj[find_index].nr_seq_num%=10000000;
	}
	else if(type == 1)
	{
		if(seq_buf.seq_obj[find_index].nd_seq_num == 0)
			seq_buf.seq_obj[find_index].nd_seq_num++;
		sprintf(out_seq,"%05ld",seq_buf.seq_obj[find_index].nd_seq_num);
		seq_buf.seq_obj[find_index].nd_seq_num++;
		seq_buf.seq_obj[find_index].nd_seq_num%=100000;
	}
	else
	{
		if(seq_buf.seq_obj[find_index].ne_seq_num == 0)
			seq_buf.seq_obj[find_index].ne_seq_num++;
		sprintf(out_seq,"%05ld",seq_buf.seq_obj[find_index].ne_seq_num);
		seq_buf.seq_obj[find_index].ne_seq_num++;
		seq_buf.seq_obj[find_index].ne_seq_num%=100000;
	}
	store_seq();
	return 1;
}


