/**********************************************************************
 
	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.

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


#include	"memory_debug.h"
#include	"xl.h"
#include	"xlerror.h"
#include	"utils.h"
#include	"acrp.h"

XL_SEXP * xl_Get();
XL_SEXP * gb_Get();
XL_SEXP * get_op();


#define MODE_DATA	0
#define MODE_META	1
#define MODE_MPT	2
#define MODE_LUMP	3

void
init_gb_Get(XLISP_ENV * env)
{
	set_env(env,l_string(std_cm,"Get"),
		get_func_prim(gb_Get,FO_APPLICATIVE,0,2,2));
}


XL_SEXP *
meta_Get(XLISP_ENV * env,XL_SEXP * s)
{
L_CHAR * pref;
L_CHAR * _filename;
XL_SEXP * filename;
XL_SEXP * ret;
XL_SEXP * cid;
XL_SEXP * mod;
int len;
unsigned int _mod;
	filename = get_el(s,1);
	if ( get_type(filename) != XLT_STRING )
		goto type_missmatch;
	len = l_strlen(filename->string.data);
	_filename = d_alloc((len+10)*sizeof(L_CHAR));
	l_strcpy(_filename,filename->string.data);
	pref = &_filename[len];

	l_strcpy(pref,l_string(std_cm,".mta"));
	ret = get_op(env,s,_filename);
	if ( get_type(ret) == XLT_ERROR )
		return ret;

	l_strcpy(pref,l_string(std_cm,""));

	_mod = get_file_modify(_filename,".mta");
	mod = List(
			n_get_symbol("modify"),
			get_integer(_mod,l_string(std_cm,"sec")),
			-1);


	if ( l_strcmp(&_filename[len-4],l_string(std_cm,".crd")) )
		goto pattern_a;


	cid = get_cid_sexp_fast(_filename);
	if ( get_type(cid) == XLT_NULL ) {
	pattern_a:
		return List(
			get_el(ret,0),
			cons(n_get_symbol("meta"),
				cons(mod,cdr(get_el(ret,1)))),
			-1);
	}
	return List(
		get_el(ret,0),
		cons(n_get_symbol("meta"),
			cons(mod,
			cons(cid,cdr(get_el(ret,1))))),
		-1);
type_missmatch:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"Get"),
		n_get_string("type missmatch"));
}

XL_SEXP *
lump_Get(XLISP_ENV * env,XL_SEXP * s)
{
L_CHAR * pref;
L_CHAR * _filename;
XL_SEXP * filename;
XL_SEXP * ret;
XL_SEXP * cid;
int len;
	filename = get_el(s,1);
	if ( get_type(filename) != XLT_STRING )
		goto type_missmatch;
	len = l_strlen(filename->string.data);
	_filename = d_alloc((len+10)*sizeof(L_CHAR));
	l_strcpy(_filename,filename->string.data);
	pref = &_filename[len];

	l_strcpy(pref,l_string(std_cm,".lmp"));
	ret = get_op(env,s,_filename);
	return get_el(ret,1);
type_missmatch:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"Get"),
		n_get_string("type missmatch"));
}

XL_SEXP *
net_mpt_entry(XL_SEXP * ent)
{
	return List(
		get_el(ent,0),
		get_el(ent,1),
		get_el(ent,2),
		get_el(ent,3),
		get_el(ent,4),
		-1);
}

XL_SEXP *
net_mpt_level(XL_SEXP * lev)
{
XL_SEXP * level_no;
XL_SEXP * ret;
	lev = cdr(lev);
	level_no = car(lev);
	lev = cdr(lev);
	ret = 0;
	for ( ; get_type(lev) ; lev = cdr(lev) ) {
		ret = cons(
			net_mpt_entry(car(lev)),
			ret);
	}
	return cons(n_get_symbol("level"),
		cons(level_no,ret));
}

XL_SEXP *
network_mpt(XL_SEXP * mpt)
{
XL_SEXP * ret;

	ret = 0;
	mpt = cdr(mpt);
	for ( ; get_type(mpt) ; mpt = cdr(mpt) ) {
		ret = cons(
			net_mpt_level(car(mpt)),
			ret);
	}
	return cons(n_get_symbol("mpt"),ret);
}

XL_SEXP *
mpt_Get(XLISP_ENV * env,XL_SEXP * s)
{
XL_SEXP * filename;
XL_SEXP * ret;
XL_SEXP * cid;
int len;
MAP_PATH_TABLE * t, * t1;
int i,j;
ACRP_DIR * d;
ACRP_ENTRY * e;
	filename = get_el(s,1);
	if ( get_type(filename) != XLT_STRING )
		goto type_missmatch;
	t = get_mpi_cp_mpt(0,filename->string.data,MPI_NOCACHE);
	if ( t == 0 )
		goto err;
	for ( t1 = t ; t1 ; t1 = t1->next ) {
		for ( i = 0 ; i < ACRP_SUBID_NOS ; i ++ ) {
			e = &t1->ent[i];
			for ( j = 1 ; j < ACRP_DIR_NOS ; j ++ ) {
				d = &e->dir[j];
				if ( d->hops < 0 )
					break;
				free_mpt_entry_dir(d);
			}
		}
	}
	ret = fileimage_of_mpt(t),
	free_mpt(t);
	return ret;
err:
	return cons(n_get_symbol("mpt"),0);
type_missmatch:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"Get"),
		n_get_string("type missmatch"));
}


XL_SEXP *
gb_Get(XLISP_ENV * env,XL_SEXP * s,
	XLISP_ENV * a,
	XL_SYM_FIELD * sf)
{
int mode;
XL_SEXP * ret;


	mode = MODE_DATA;
	for ( ; sf ; sf = sf->next ) {
		if ( l_strcmp(sf->name,l_string(std_cm,"mode")) == 0 ) {
			if ( l_strcmp(sf->data,l_string(std_cm,"meta"))
					 == 0 ) {
				mode = MODE_META;
			}
			else if ( l_strcmp(sf->data,
					l_string(std_cm,"data")) == 0 ) {
				mode = MODE_DATA;
			}
			else if ( l_strcmp(sf->data,
					l_string(std_cm,"mpt")) == 0 ) {
				mode = MODE_MPT;
			}
			else if ( l_strcmp(sf->data,
					l_string(std_cm,"lump")) == 0 ) {
				mode = MODE_LUMP;
			}
		}
	}
	switch ( mode ) {
	case MODE_DATA:
		ret = xl_Get(env,s,a,sf);
		break;
	case MODE_META:
		ret = meta_Get(env,s);
		break;
	case MODE_MPT:
		ret = mpt_Get(env,s);
		break;
	case MODE_LUMP:
		ret = lump_Get(env,s);
		break;
	default:
		er_panic("gb_Get");
	}
	return ret;
}

