#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "../../snmp/src/include/snmp.h"
#include "../../snmp/src/include/macro.h"

#include "roaming_rule.h"
#include "../../public/src/uwav/numgrp.h"
#include "../../public/src/uwav/number.h"

_roaming_rule_table	rr_table;

#define ASN_1_OCTET_STRING	4
#define ASN_1_INTEGER		2
struct numgrp_table	*xapp_rr_ptr=NULL;
extern void xap_set_roaming_rule_flag();
extern int ParseLineWithDot(char *str, char (*row)[128], int maxrow);
extern int ParseLineWithSquare(char *str, char (*row)[128], int maxrow);
extern int xap_get_response(u8 oidlen,u32 *oid,u8 *pdata,u8 *vartype);
extern int xap_set_response(u8 oidlen,u32 *oid,u8 *pdata,u16 datalen);
extern void 	xap_set_roaming_rule_param_flag();
/*------------------------------------------------------------------*/

int	xap_save_roaming_rule()
{
	char	filename[]="./conf/roaming_rules.conf";
	int   i;
	FILE	*fpConf  = NULL;
	_roaming_rule *ptr=NULL;
	
	fpConf = fopen(filename,"w");
	if(fpConf == NULL) 
		return 0;

	for(i=0; i<MAX_RULES; i++)
	{
		ptr = &rr_table.roaming_rule[i];
		if(ptr->used_flag == 1)
			fprintf(fpConf, "%04d.%s.%d.%d.%d.%d.%d.%d.%d\r\n",
				ptr->id, ptr->prefix, ptr->lu_action, ptr->reject_cause,
				ptr->vlr_counter, ptr->no_voice_camel, 
				ptr->no_sms_camel, 
				ptr->smsc_camel_if,
				ptr->routing_home);						
	}
	fclose(fpConf);
	return 1;
}

int xap_read_roaming_rule_record(char * s)
{
	char	LineInfo[10][128]={{0}, {0}};
	char	DetailInfo[10][128]={{0}, {0}};
	int		rtn;
	int		Instance;
	_roaming_rule *ptr;
	
	rtn = ParseLineWithSquare(s, LineInfo, 1);
	rtn = ParseLineWithDot(LineInfo[0],DetailInfo, 9);
	Instance = strtoll(DetailInfo[0],NULL,10);
	if(Instance >= MAX_RULES)
	{
		return 0;
	}
	ptr = &rr_table.roaming_rule[Instance];
	ptr->used_flag = 1;
	ptr->id = Instance;
	strcpy(ptr->prefix , DetailInfo[1]);
	ptr->lu_action = atoi(DetailInfo[2]);
	ptr->reject_cause = atoi(DetailInfo[3]);
	ptr->vlr_counter = atoi(DetailInfo[4]);
	ptr->no_voice_camel = atoi(DetailInfo[5]);
	ptr->no_sms_camel = atoi(DetailInfo[6]);
	ptr->smsc_camel_if = atoi(DetailInfo[7]);
	ptr->routing_home = atoi(DetailInfo[8]);

	return 1;
}

int xap_read_roaming_rule()
{
	char filename[]="./conf/roaming_rules.conf";
	FILE *fp=NULL;
	char record[128];
	int    len;
	
	fp = fopen(filename, "r");
	if(fp == NULL)
		return 0;

	memset(&rr_table, 0x00, sizeof(_roaming_rule_table));

	while ( fgets(record, 128, fp) != (char *)0 )
	{
		if ( (int *)strchr(record,'#') != NULL ) continue;
		if ( (len=strlen(record))==0 ) continue;
		if(record[0]=='\n')continue;
		
		xap_read_roaming_rule_record(record);		
	}
	
	fclose(fp);
	return 1;
}

int xap_create_roaming_rule_table()
{
	int	i,len;
	struct number_group tmp_num_grp;

	if( xapp_rr_ptr!= NULL)
		delete_numgrp_table(xapp_rr_ptr);

	xapp_rr_ptr = assign_numgrp_table("rrule",MAX_RULES);
	for(i=0;i<MAX_RULES;i++)
	{
		len = strlen(rr_table.roaming_rule[i].prefix);
		if(len<1 && len>MAX_PREFIX_LEN) 
			continue;
		tmp_num_grp.start.num_of_digit = len;
		memcpy(tmp_num_grp.start.digit, rr_table.roaming_rule[i].prefix, len);
		tmp_num_grp.end.num_of_digit = len;
		memcpy(tmp_num_grp.end.digit, rr_table.roaming_rule[i].prefix, len);
		tmp_num_grp.index = i;

		numgrp_insert(xapp_rr_ptr,
			&tmp_num_grp.start,
			&tmp_num_grp.end,
			tmp_num_grp.index);
	}
	return 0;
}

int	xap_search_roaming_rule_table(char * vlr_number)
{
	num16_t num16_tmp;
	int	result=-1;
	int	len, maxlen=0;
	register int i;
	

	for(i=0; i<MAX_RULES; i++)
	{
		if(rr_table.roaming_rule[i].used_flag)
		{
			len = strlen(rr_table.roaming_rule[i].prefix);
			if(strncasecmp(vlr_number, rr_table.roaming_rule[i].prefix, len) ==0)
			{
				if(len>maxlen)
				{
					maxlen = len;
					result = i;
				}
			}
		}
	}

	return result;

	if(xapp_rr_ptr==NULL) return -1;
	
	if(len==0) return -1;
	if(len>MAX_PREFIX_LEN) len = MAX_PREFIX_LEN;

	num16_tmp.num_of_digit = len;
	memcpy(num16_tmp.digit,vlr_number,len);
	if(numgrp_search(&result, xapp_rr_ptr, &num16_tmp))
		return result;
	
	return -1;
}

int xap_roaming_rule_get_rule(char *vlr_number, _roaming_rule *ptr)
{
	int index=-1;

	if((index = xap_search_roaming_rule_table(vlr_number))< 0)
		return 0;
	
	memcpy(ptr, &rr_table.roaming_rule[index], sizeof(_roaming_rule));;

	return 1;
}

int xap_roaming_rule_get_smsc_camel_flag(char *vlr_number)
{
	int index=-1;
	_roaming_rule *ptr= NULL;
	
	if((index = xap_search_roaming_rule_table(vlr_number))< 0)
		return 0;
	
	ptr = &rr_table.roaming_rule[index];
	return ptr->smsc_camel_if;
}

int xap_roaming_rule_get_routing_home_flag(char *vlr_number)
{
	int index=-1;
	_roaming_rule *ptr= NULL;
	
	if((index = xap_search_roaming_rule_table(vlr_number))< 0)
		return -1;
	
	ptr = &rr_table.roaming_rule[index];
	return ptr->routing_home;
}

int xap_roaming_rule_test(char *vlr_number)
{
	_roaming_rule ptr;

	if(xap_roaming_rule_get_rule(vlr_number, &ptr)) 
	{
		return ptr.id;
	}
	return -1;
}
/* ---------------------------------------------------------------------------*/
/* ------------------------ function: xap_get_idle_index() -------------------*/
/* -- return =0 ,failed, otherwise succeed -----------------------------------*/
/* ---------------------------------------------------------------------------*/
int xap_get_roaming_rule_idle_index(int type, int *newID)
{
	int i;

	switch(type)
	{
		case 1:
			for(i=0;i<MAX_RULES;i++)
			{
				if(rr_table.roaming_rule[i].used_flag == 0)
				{
					*newID = i;
					return 1;
				}
			}
		break;
		default:
		break;
	}
	return 0;
}

/* --------------------- */
/* -- prefix routines -- */
/* --------------------- */

int xap_getnext_roaming_rule(u32 *index_id)
{
	int 		i;

	for(i = *index_id; i < MAX_RULES; i++)
	{	
		if(rr_table.roaming_rule[i].used_flag)
		{
			*index_id = i;
			return 1;
		}
	}
	*index_id = 0;
	return 0;
}

int xap_get_roaming_rule(u32 column, u32 *instance, u_char *pdata, u_char *vartype)
{
	int datalen = 0,index;
	
	index = instance[0];
	if(index < 0 || index >= MAX_RULES )
		return -1;
	if(rr_table.roaming_rule[index].used_flag == 0)
		return -1;
	
	*vartype = ASN_1_OCTET_STRING;
	switch(column)
	{
		case 1: /* index */
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = index;
			break;
		case 2: 
			datalen = strlen(rr_table.roaming_rule[index].prefix);
			memcpy(pdata,rr_table.roaming_rule[index].prefix,datalen);
			//if(datalen == 0) datalen = 1;
		break;
		case 3:  
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = rr_table.roaming_rule[index].lu_action;
		break;
		case 4:  
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = rr_table.roaming_rule[index].reject_cause;
		break;
		case 5:  
			*vartype = ASN_1_INTEGER;
			datalen = 4;
			pdata[0] = rr_table.roaming_rule[index].vlr_counter>>24;
			pdata[1] = rr_table.roaming_rule[index].vlr_counter>>16;
			pdata[2] = rr_table.roaming_rule[index].vlr_counter>>8;
			pdata[3] = rr_table.roaming_rule[index].vlr_counter;			
		break;
		case 6:  
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = rr_table.roaming_rule[index].no_voice_camel;
		break;
		case 7:  
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = rr_table.roaming_rule[index].no_sms_camel;
		break;
		case 8:  
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = rr_table.roaming_rule[index].smsc_camel_if;
		break;
		case 9:
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = rr_table.roaming_rule[index].routing_home;
		break;		
		case 10:  
			*vartype = ASN_1_INTEGER;
			pdata[0] = 1; /* active */	
			datalen = 1;
		break;
		default:
			return -1;
		break;			
	}
	return datalen;
}


int xap_set_roaming_rule(u32 column, u32 *instance, u_char *pdata, unsigned short datalen)
{
	int	index;
	//int	newId;
		
	//if(datalen == 0)
	//	return -1;

	index = instance[0];
	if(index < 0 || index >= MAX_RULES)
		return -1;
	
	xap_set_roaming_rule_flag();
	switch(column)
	{
		case 1:/* create	*/
			index = pdata[0];
			if(index < 0 || index >= MAX_RULES)
				return -1;
			else
			{
				rr_table.roaming_rule[index].used_flag = 1;
				rr_table.roaming_rule[index].id = index;
			}
			
		break;
		case 2: /* prefix */
			if(datalen>=MAX_PREFIX_LEN)
				return -1;
			memset(rr_table.roaming_rule[index].prefix, 0x00, MAX_PREFIX_LEN);
			memcpy(rr_table.roaming_rule[index].prefix, pdata, datalen);
			break;
		case 3: 
			if(pdata[0]>=2)
				return -1;
			rr_table.roaming_rule[index].lu_action = pdata[0];
			break;
		case 4: 
			rr_table.roaming_rule[index].reject_cause = pdata[0];
			break;
		case 5: 
			if(datalen>=5)
				return -1;
                      {
                                if(datalen==1)
                                         rr_table.roaming_rule[index].vlr_counter = pdata[0];
                                else
                                         rr_table.roaming_rule[index].vlr_counter = pdata[0]*256+pdata[1];
                        }
   		break;
		case 6: 
			if(pdata[0]>2)
				return -1;
			rr_table.roaming_rule[index].no_voice_camel = pdata[0];
			break;
		case 7: 
			if(pdata[0]>2)
				return -1;
			rr_table.roaming_rule[index].no_sms_camel = pdata[0];
			break;
		case 8: 
			if(pdata[0]>2)
				return -1;
			rr_table.roaming_rule[index].smsc_camel_if = pdata[0];
			break;
		case 9: 
			rr_table.roaming_rule[index].routing_home = pdata[0];
			break;			
		case 10:  /* status */
			if(pdata[0] == 6) /* 6==delete */
			{
			    memset(&rr_table.roaming_rule[index] ,0x00 ,sizeof(_roaming_rule));			
			}
		break;	
		default:
			return -1;
		break;
	}
	return datalen;
}

int xap_roaming_rules_init()
{
	xap_read_roaming_rule();
//	xap_create_roaming_rule_table();
	return 1;
}
