/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/


#ifndef ___ACRP_H___
#define ___ACRP_H___


/* mapping path table

(mpt
(regulation 123)
(level 0
	(entry	id
		"pri"
		sum
		(dir	hops1
			"map1"
			"crd1")
		(dir
			hops2
			"map2"
			"crd2")
		...
		)
	(entry	...)
	....)
)

*/

#include	"xl.h"

#define ID_TOLERANCE	45

#define ACRP_SUBID_BIT	7
#define ACRP_SUBID_NOS	(1<<ACRP_SUBID_BIT)
#define ACRP_DIR_NOS	2

#define MPI_LL_MAX	1000
#define REGULATION_TIMEOUT	30

#define ACRP_MIN_INTERVAL	5
#define ACRP_MAX_INTERVAL	(24*3600)
#define MODIFY_CHECK_INTERVAL	60

#define MAX_TTL		100
#define DEFAULT_TTL	10

typedef struct acrp_dir {
	int		flags;
#define ADF_CHECK	0x00000001
	int		hops;
	L_CHAR *	map;
	L_CHAR *	crd;
} ACRP_DIR;

typedef struct acrp_entry {
	L_CHAR *	pri;
	int		sum;
	ACRP_DIR		dir[ACRP_DIR_NOS];
} ACRP_ENTRY;


typedef struct map_path_table {
	struct map_path_table *	next;
	int			level;
	int			id;
	ACRP_ENTRY		ent[ACRP_SUBID_NOS];
} MAP_PATH_TABLE;

typedef struct mpi_header {
	struct map_path_info *	next;
	struct map_path_info *	prev;
} MPI_HEADER;

typedef struct around_list {
	struct around_list *	next;
	L_CHAR *		crd;
	L_CHAR *		map;
	L_CHAR *		me;
	MAP_PATH_TABLE *	mpt;
} AROUND_LIST;

typedef struct map_path_info {
	MPI_HEADER		h;
	int			sts;
#define MPIS_ERROR		0
#define MPIS_LOCAL		1
#define MPIS_REMOTE		2
#define MPIS_FETCH		3
	int			lock;
	/* if dirty lock == -2 */

	URL			u;
	unsigned int		regulation;
	L_CHAR *		my_pri;
	unsigned int		modify;

	MAP_PATH_TABLE *	mpt;

	char			cid_flag;
/* cid_flag = 1 cid is not set */
	char			alist_fetch;
/* alist_fetch = 1 already fetch */
	AROUND_LIST *		alist;
} MAP_PATH_INFO;

typedef struct map_path {
	ACRP_ENTRY 		ent;
	int			dir;
	L_CHAR *		map;
	L_CHAR *		crd;
} MAP_PATH;

#define MPE_FIT		(0)
#define MPE_NO_ROUTE	(-1)
#define MPE_OVER_TTL	(-2)
#define MPE_UNKNOWN	(-3)
#define MPE_OTHER_SITE	(-4)

MAP_PATH_TABLE * new_mpt();
void
free_mpt_entry_dir(ACRP_DIR * d);
void
free_mpt_entry(ACRP_ENTRY * e);
void
free_mpt(MAP_PATH_TABLE * m);
MAP_PATH_TABLE *
get_mpt(unsigned int * reg,int * cid_flag,XL_SEXP * s);
int *
get_cid(L_CHAR ** ret_pri,L_CHAR ** ret_body,L_CHAR * filename);
int *
_get_cid(L_CHAR ** ret_pri,L_CHAR ** ret_body,MAP_PATH_TABLE * mpt);
XL_SEXP *
get_cid_sexp(L_CHAR * filename);
XL_SEXP *
_get_cid_sexp(MAP_PATH_INFO*);
MAP_PATH_INFO *
get_mpi(int ses,L_CHAR * url_str,int type);

#define MPI_TYPE	0x0ffff
#define MPI_READ	1
#define MPI_WRITE	2
#define MPI_NOCACHE	0x10000

MAP_PATH_TABLE *
copy_mpt(MAP_PATH_TABLE * m);
MAP_PATH_TABLE *
get_mpi_cp_mpt(int ses,L_CHAR * url_str,int type);
void
trigger_mpi(MAP_PATH_INFO * m);
void
dirty_mpi(MAP_PATH_INFO * m);
XL_SEXP *
cid2list(int * cid);
int
cmp_site(L_CHAR * s1,int ip1,int p1,L_CHAR * s2,int ip2,int p2);
int *
url2cid(L_CHAR * url);
int *
list2cid(XL_SEXP * s);
int get_acrp_port();
XL_SEXP *fileimage_of_mpi(MAP_PATH_INFO * mpi);
XL_SEXP *fileimage_of_mpt(MAP_PATH_TABLE *);

int addr_length(MAP_PATH_TABLE * );

int
MP_routing(int ses,
	   int *,MAP_PATH * mp,int ttl,L_CHAR * url,int * target,int type,
	   int option);
int
MP_routing_over_site(
	int * len,
	MAP_PATH * mp,int ttl,L_CHAR * url,int * target,int mode,
	int ret_mode,int option);
#define MPR_EFFORT	0xf
#define MPR_BEST	0x0
#define MPR_FAST	0x1

#define MPR_RETURN	0xf0
#define MPR_ROUTE	0x00
#define MPR_TARGET	0x10

XL_SEXP *
filtering_crd(XL_SEXP * s);
void
get_sd_url(L_CHAR ** src,L_CHAR ** dest,L_CHAR ** map,XL_SEXP * s);
XL_SEXP *
get_crd_chi(L_CHAR * filename);
XL_SEXP *
get_crd_par(L_CHAR * filename);

void
free_mp(MAP_PATH * mp,int len);
void
reset_mp(MAP_PATH * mp,int len);

XL_SEXP *
filtering_crd(XL_SEXP * s);
void
set_mpi_around_list(MAP_PATH_INFO * mpi,
	AROUND_LIST * a,
	int copy_flag);
AROUND_LIST *
get_mpi_around(MAP_PATH_INFO * mpi);
void
free_around_list(AROUND_LIST * a);
AROUND_LIST *
copy_around_list(AROUND_LIST * a);
L_CHAR *
get_access_path(URL * u,char * prefix);
XL_SEXP *
get_cid_sexp_fast(L_CHAR * filename);

#endif

