/**********************************************************************
 
	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	"xlerror.h"
#include	"xl.h"
#include	"proxy.h"

XL_SEXP * xl_SetProxy();

extern int http_proxy_keep_alive_mode;

void
init_SetProxy(XLISP_ENV * env)
{
	set_env(env,l_string(std_cm,"SetProxy"),
		get_func_prim(xl_SetProxy,FO_APPLICATIVE,0,1,1));
}



L_CHAR *
get_server(L_CHAR * ptr,char ** server)
{
L_CHAR * ret;
L_CHAR * buf;
char * _buf;
char * p;
int len;
	for ( ; *ptr &&
		(*ptr == ' ' ||
		*ptr == '\t' ||
		*ptr == '\n' ||
		*ptr == '\r' ||
		*ptr == ',' );
		ptr ++ );
	if ( *ptr == 0 ) {
		*server = 0;
		return ptr;
	}
	for ( ret = ptr ; *ret && 
		*ret != ',' && 
		*ret != ' ' &&
		*ret != '\t' &&
		*ret != '\n' &&
		*ret != '\r'
		; ret ++ );
	len = ret - ptr;
	buf = d_alloc(sizeof(L_CHAR)*(len+1));
	memcpy(buf,ptr,sizeof(L_CHAR)*(len+1));
	buf[len] = 0;
	if ( *ret )
		ret ++;
	_buf = ln_copy_str(std_cm,buf);
	d_f_ree(buf);
	*server = _buf;
	return ret;
}

SERVER_LIST *
get_da_server(L_CHAR * da_list)
{
SERVER_LIST * ret,* sl;
	ret = 0;
	for ( ; *da_list ; ) {
		sl = d_alloc(sizeof(*sl));
		sl->next = 0;
		da_list = get_server(da_list,
			&sl->name);
		if ( sl->name == 0 ) {
			d_f_ree(sl);
			break;
		}
		sl->next = ret;
		ret = sl;
	}
	return ret;
}


XL_SEXP *
xl_SetProxy(XLISP_ENV * env,XL_SEXP * s,
	XLISP_ENV * a,
	XL_SYM_FIELD * sf)
{
L_CHAR * type;
L_CHAR * da_servers;
L_CHAR * proxy_server;
L_CHAR * proxy_port;
L_CHAR * da_list;
L_CHAR * keep_alive;
char * _proxy_server;
int _proxy_port;
char _type;
SERVER_LIST * sl, * sl2;
	type = get_sf_attribute(sf,l_string(std_cm,"type"));
	if ( l_strcmp(type,l_string(std_cm,"NoProxy")) == 0 )
		_type = PT_NO_PROXY;
	else if ( l_strcmp(type,l_string(std_cm,"HTTPProxy")) == 0 )
		_type = PT_HTTP_PROXY;
	else if ( l_strcmp(type,l_string(std_cm,"NativeProxy")) == 0 )
		_type = PT_NATIVE_PROXY;
	else if ( l_strcmp(type,l_string(std_cm,"XLoHTTP")) == 0 )
		_type = PT_XLoHTTP;
	else {
		return get_error(
			s->h.file,
			s->h.line,
			XLE_PROTO_INV_PARAM,
			l_string(std_cm,"SetProxy"),
			n_get_string("invalid proxy type"));
			
	}

	da_list = get_sf_attribute(sf,l_string(std_cm,"direct"));
	if ( da_list )
		goto da_proc;

	if ( (_type&(PT_NO_PROXY|PT_HTTP_PROXY|PT_NATIVE_PROXY))
			== 0 )
		goto inv_type;

	proxy_server = get_sf_attribute(sf,l_string(std_cm,"server"));
	if ( proxy_server ) {
		if ( get_server(
				proxy_server,
				&_proxy_server) == 0 )
			goto inv_proxy_server;
		proxy_port = get_sf_attribute(sf,l_string(std_cm,"port"));
		if ( proxy_port == 0 )
			goto inv_proxy_port;
		_proxy_port = atoi(n_string(std_cm,proxy_port));
	}
	else {
		_proxy_server = 0;
	}
	keep_alive = get_sf_attribute(sf,l_string(std_cm,"keep-alive"));
	if ( keep_alive ) {
		if ( l_strcmp(keep_alive,l_string(std_cm,"off")) == 0 )
			http_proxy_keep_alive_mode = 0;
		else	http_proxy_keep_alive_mode = XoH_F_KEEP_ALIVE;
	}
	set_proxy(_type,_proxy_server,_proxy_port);
	if ( _proxy_server )
		d_f_ree(_proxy_server);
	return 0;
da_proc:
	if ( (_type&(PT_NO_PROXY|PT_XLoHTTP)) == 0 )
		goto inv_type;
	sl = get_da_server(da_list);
	if ( sl == 0 )
		goto inv_da_list;
	for ( sl2 = sl ; sl2 ; sl2 = sl2->next )
		set_direct_access(_type,sl2->name);
	free_server_list(sl);
	return 0;
type_missmatch:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"SetProxy"),
		0);
inv_proxy_server:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_PROTO_INV_PARAM,
		l_string(std_cm,"SetProxy"),
		n_get_string("proxy server is required"));
inv_proxy_port:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_PROTO_INV_PARAM,
		l_string(std_cm,"SetProxy"),
		n_get_string("proxy server port is required"));
inv_type:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_PROTO_INV_PARAM,
		l_string(std_cm,"SetProxy"),
		List(
			n_get_string("invalid proxy type"),
			get_string(type),
			-1));
inv_da_list:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_PROTO_INV_PARAM,
		l_string(std_cm,"SetProxy"),
		n_get_string("invalid direct parameter"));
}


