#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <unistd.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif


#include <ccn/ccn.h>
#include <ccn/uri.h>
#include <ccn/keystore.h>
#include <ccn/signing.h>
#include <ccn/schedule.h>
#include <ccn/hashtb.h>


#include "nlsr.h"
#include "nlsr_km_util.h"
#include "nlsr_km.h"

int
appendLifetime(struct ccn_charbuf *cb, int lifetime) 
{
	unsigned char buf[sizeof(int32_t)];
	int32_t dreck = lifetime << 12;
	int pos = sizeof(int32_t);
	int res = 0;
	while (dreck > 0 && pos > 0) 
	{
		pos--;
		buf[pos] = dreck & 255;
		dreck = dreck >> 8;
	}
	res |= ccnb_append_tagged_blob(cb, CCN_DTAG_InterestLifetime, buf+pos, 
															sizeof(buf)-pos);
	return res;
}

int
contain_key_name(const unsigned char *ccnb, struct ccn_parsed_ContentObject *pco) 
{
	if (pco->offset[CCN_PCO_B_KeyLocator] == pco->offset[CCN_PCO_E_KeyLocator])
		return -1;

	struct ccn_buf_decoder decoder;
	struct ccn_buf_decoder *d;
	d = ccn_buf_decoder_start(&decoder, ccnb + 
		pco->offset[CCN_PCO_B_Key_Certificate_KeyName], 
		pco->offset[CCN_PCO_E_Key_Certificate_KeyName] - 
		pco->offset[CCN_PCO_B_Key_Certificate_KeyName]);
	if (ccn_buf_match_dtag(d, CCN_DTAG_KeyName))
		return 1;

	return -1;
}

struct ccn_charbuf *
get_key_name(const unsigned char *ccnb, struct ccn_parsed_ContentObject *pco) 
{
	struct ccn_charbuf *key_name = ccn_charbuf_create();
	ccn_charbuf_append(key_name, ccnb + pco->offset[CCN_PCO_B_KeyName_Name], 
	pco->offset[CCN_PCO_E_KeyName_Name] - pco->offset[CCN_PCO_B_KeyName_Name]);

	return key_name;
}


int
check_for_name_component_in_name(const struct ccn_charbuf *name, 
								const struct ccn_indexbuf *indx,
								const char *component){
	
	int res,i;
	int result_position=0;
	int name_comps=(int)indx->n;

	for(i=0;i<name_comps;i++){
		res=ccn_name_comp_strcmp(name->buf,indx,i,component);
		if( res == 0){
			
				result_position=i;
				break;
		}	
	}

	return result_position;
}


int
check_for_tag_component_in_name(const struct ccn_charbuf *name, 
								const struct ccn_indexbuf *indx,
								const char *component){
	
	int res,i;
	int result_position=0;
	int name_comps=(int)indx->n;

	for(i=0;i<name_comps;i++){
		const unsigned char *comp_ptr;
		size_t comp_size;
		res=ccn_name_comp_get(name->buf, indx,i,&comp_ptr, &comp_size);
		if( res == 0){
			if ( strstr((char *)comp_ptr,component) != NULL ){
				result_position=i;
				break;
			}
		}	
	}

	return result_position;
}

enum key_type
get_key_type_from_key_name(struct ccn_charbuf *keyname)
{
	if ( nlsr->debugging )	
		printf("get_key_type_from_key_name called\n");

	int res;
	int return_key=UNKNOWN_KEY;	

	struct ccn_indexbuf *indx=ccn_indexbuf_create();
	if ( indx == NULL ){
		if ( nlsr->debugging )
			printf("Error in creating index for key name \n");
		return UNKNOWN_KEY;
	}

	res=ccn_name_split(keyname,indx);
	if ( res < 0 ){
		if ( nlsr->debugging )
			printf("Error in parsing key name \n");
		ccn_indexbuf_destroy(&indx);
		return UNKNOWN_KEY;
	}
	else if ( res == 3){
		int chk_ndn=check_for_name_component_in_name(keyname,indx,"ndn");
		int chk_key=check_for_name_component_in_name(keyname,indx,"keys");
		if ( chk_ndn == 0 && chk_key == 1)
			return_key=ROOT_KEY;
	}
	else{
		int check_op,check_rt;
		check_op=check_for_tag_component_in_name(keyname,indx,
													 "O.N.Start");
		check_rt=check_for_tag_component_in_name(keyname,indx,
													 "R.N.Start");
		if ( check_op > 0){
			return_key=OPERATOR_KEY;
		}
		else if(check_rt >0){
			int check_nlsr;
			check_nlsr=check_for_name_component_in_name(keyname,indx,
													 "nlsr");
			if ( check_rt > 0 ){
				if ( check_nlsr > 0){
					return_key=NLSR_KEY;
				}
				else{
					return_key=ROUTING_KEY;
				}
			}
		}
		else if ( check_rt == 0 && check_op == 0 && res > 3){
			return_key=SITE_KEY;
		}
	}

	ccn_indexbuf_destroy(&indx);
	return return_key;
}


char *
get_name_segments_from_name(struct ccn_charbuf *name, int start_indx, int end_indx) 
{
	int res;	
	struct ccn_indexbuf *name_comps;
	struct ccn_charbuf *orig_router;
	char *name_seg=NULL;

	name_comps = ccn_indexbuf_create();
	res = ccn_name_split(name, name_comps);
	if ( res < 0 ){
		ccn_indexbuf_destroy(&name_comps);
		return name_seg;
	}
	else{		
		orig_router=ccn_charbuf_create();
		ccn_name_init(orig_router);	
		ccn_name_append_components(orig_router,name->buf,
										name_comps->buf[start_indx], 
										name_comps->buf[end_indx]);
		struct ccn_charbuf *temp1=ccn_charbuf_create();
		ccn_uri_append(temp1, orig_router->buf, orig_router->length, 0);

		name_seg=(char *)calloc(strlen(ccn_charbuf_as_string(temp1))+1,
																sizeof(char));
		memcpy(name_seg,ccn_charbuf_as_string(temp1),
										strlen(ccn_charbuf_as_string(temp1)));
		name_seg[strlen(name_seg)]='\0';
		ccn_charbuf_destroy(&orig_router);
		ccn_charbuf_destroy(&temp1);
		
	}	

	ccn_indexbuf_destroy(&name_comps);
	return name_seg;
}


char *
get_orig_router_from_key_name(struct ccn_charbuf *name, int more, int type) 
{
	int res;	
	struct ccn_indexbuf *name_comps;
	struct ccn_charbuf *orig_router;
	char *router=NULL;

	name_comps = ccn_indexbuf_create();
	res = ccn_name_split(name, name_comps);
	if ( res < 0 ){
		ccn_indexbuf_destroy(&name_comps);
		return router;
	}
	else{
		res=ccn_name_chop(name, name_comps, -(2-more));
		if ( more > 0 && type==1)
		res=ccn_name_chop(name, name_comps, -3);
		if ( res < 0 ){
			ccn_indexbuf_destroy(&name_comps);
			return NULL;
		}
		else{
			res=check_for_tag_component_in_name(name,name_comps,"R.N.Start");
			if ( res > 0 ){
				orig_router=ccn_charbuf_create();
				ccn_name_init(orig_router);	
				ccn_name_append_components(orig_router,name->buf,
										name_comps->buf[res+1], 
										name_comps->buf[name_comps->n - 1]);
				struct ccn_charbuf *temp1=ccn_charbuf_create();
				ccn_uri_append(temp1, orig_router->buf, orig_router->length, 0);

				router=(char *)calloc(strlen(ccn_charbuf_as_string(temp1))+1,
																sizeof(char));
				memcpy(router,ccn_charbuf_as_string(temp1),
										strlen(ccn_charbuf_as_string(temp1)));
				router[strlen(router)]='\0';
				ccn_charbuf_destroy(&temp1);
				ccn_charbuf_destroy(&orig_router);
			}
			else{
				ccn_indexbuf_destroy(&name_comps);
				return NULL;
			}
		}
	}	

	ccn_indexbuf_destroy(&name_comps);
	return router;
}

