%%% File:     ixgatekeeper.pl
%%% Author:   Stephen Potter <stephenp@cara.aiai.ed.ac.uk>
%%% Created:  Tue Apr 23 2002

%%%
%%% If LINDA is to be used, there would seem to be a need for
%%% some sort of gatekeeping service that would mediate between
%%% the tuplespace and the AKT-bus (and hence possibly remote)
%%% communications.
%%% In other words, all agents would know of the existence of
%%% the gatekeeper (and its - hopefully persistent - URI),
%%% rather than knowing the address of the tuplespace. 
%%% (The broker itself is a possible exception to this; it 
%%% probably should be able to interact with the (relative to it)
%%% local tuplespace.
%%%
%%% So:
%%% - solver agents advertise their capabilities to the gatekeeper,
%%%   which can then be invoked through it.
%%% - query agents post their queries to the gatekeeper, and await
%%%   its response.
%%% - the broker need have no direct interaction with the gk (but
%%%   must address its responses into the tuplespace to it).
%%%

%%%
%%% This particular version handles messages arriving from IX
%%% systems.
%%%

%:-use_module('ixwrap.pl').
:-use_module('kraft/prolog/pillow/pillow.pl').
:- use_module('aktbus-0.3.1/prolog/src/absl.pl').
:-use_module(library('linda/client')).
:-use_module(library(lists)).
:-use_module(library(charsio)).
%:- ensure_loaded([newutil]).
:-use_module(library(system)).


:-working_directory(_,'C:/Documents and Settings/jessicac/Desktop/sim-fbpml/comm').

%[linda_server].
port(5555). % this needs to be some fixed port somewhere...

gatekeeper_address('http://summer,aiai.ed.ac.uk/:').
find_server(Server, PID) :-
    see('./common/server.addr'),
    read(server(Server, PID)),
    seen.

tester :-
	find_server(LServer,LPN),
	linda_client(LServer:LPN),
	in_noblock(broker(_Sender,_Date,_Time,C)),
	write(C),nl,
	C,
	close_client.


gatekeeper(PN) :-
	% start linda?
	% post linda ts address for broker?
	% open port connection?
	% loop:
	% await messages? (what happens with simultaneous?)
	% strip out content, and post 'appropriate' tuple
	% look into tuplespace, and pick up any addressed msgs
	% wrap up messages and pass them on...
	% etc.
	find_server(LServer,LPN),
	linda_client(LServer:LPN),
	%port(PN),
	create_aktbus_receiver(PN,RHandle),
	format("Port ~d opened\n", [PN]),
%	wait_for_msg(RHandle),
	ix_get_message(RHandle),
	!,
	destroy_aktbus_receiver(RHandle).

check_terminated(Term,Term):-
        append(_X,".",Term).
check_terminated(Term,TermT):-
        \+append(_X,".",Term),
        append(Term,".",TermT).


wait_for_msg(RHandle):-
	% here need to think about the form & content of the messages
	% that will be received:
	receive_message(RHandle,Msg),
	write(Msg),nl,
%	get_env(Msg, 'aktbus:hasContent',_,[Content|_]),
	get_env(Msg, 'aktbus:hasSimpleMessage',_,[Content|_]),
	get_env(Msg, 'aktbus:hasSenderURI',_,[SenderURI|_]),
	get_env(Msg, 'aktbus:hasDateString',_,[Date|_]),
	get_env(Msg, 'aktbus:hasTimeString',_,[Time|_]),
	%extract_content(Msg,Content),
	%write('****************************'),nl,
	%nl,write(Content),nl,%write(SenderURI),
	%name(C, Content),
	name(Content, DContent),
	clean_parse(TC1,DContent,[]),

     check_terminated(TC1,TC),
	%append(TC1,".",TC), % need to append full stop!

	read_from_chars(TC,C),

	write(C),nl,

	%name(S, SenderURI),
	%name(D, Date),
	%name(T, Time),
	(
	    (C=close_connection, % reserved atom kills service!
	    write('Connection closed'),
	    nl);

	    % this is the format of the fact written to linda:
	    (out(broker(SenderURI,Date,Time,C)), % assumes C is some meaningful tuple...
	    write('message sent to linda'),nl,
	    wait_for_msg(RHandle))
	).


ix_get_message(RHandle):-
	format("Waiting for message\n",[]),
	receive_message(RHandle,Msg),
	write(Msg),nl,
%	get_env(Msg, 'aktbus:hasContent',_,[Content|_]),
	get_env(Msg, 'aktbus:hasSimpleMessage',_,[IXMessage|_]),
	get_env(Msg, 'aktbus:hasSenderURI',_,[SenderURI|_]),
	get_env(Msg, 'aktbus:hasDateString',_,[Date|_]),
	get_env(Msg, 'aktbus:hasTimeString',_,[Time|_]),

	%parse_ix_xml(Sender,Content,IXMessage,[]),
	
	write(SenderURI),nl,
	
	name(IXMessage,IXTemp),
	clean_parse(IXT,IXTemp,[]),!,
	xml2terms(IXT,IXM),
	%name(IXM,IXT),
	write(IXM),nl,

	% IXMessage is itself xml, so this should do it:
	% (What will the content from IX look like?)
	% get_env(IXM,'statement',_,[Content|_]),
	%get_env(IXM,'string',_,[Content|_]),
	
	get_mcontentt(IXM,Content,_Type),
	% assume Content is a quoted string...(!)
	% the following is a bit of a fix...

	write(Content),
   
	((
	name(Content, TC1),
check_terminated(TC1,TC),
	%append(TC1,".",TC), % assume content ends in full stop!
	%nl,write(TC),nl,
	read_from_chars(TC,C));

	C=Content),

	%C=ok,
	write(C),nl,

	(
	    (C=close_connection, % reserved atom kills service!
	    format("Connection closed\n",[])
	    );
	    (
	    out(wfe(SenderURI,Date,Time,C)),
	    format("IX-Message processed.\n",[]),
	    ix_get_message(RHandle))
	).





clean_parse(Cleaned) --> "&quot;", clean_parse(R), {append("\"",R,Cleaned)}.
clean_parse(Cleaned) --> "&apos;", clean_parse(R), {append("\'",R,Cleaned)}.
clean_parse(Cleaned) --> "&lt;", clean_parse(R),{append("<",R,Cleaned)}.
clean_parse(Cleaned) --> "&gt;", clean_parse(R),{append(">",R,Cleaned)}.
clean_parse("") --> "".
clean_parse(Cleaned) --> [C], clean_parse(R), {append([C],R,Cleaned)}.

mypr1(X) --> "env(prolog,[],[",mypr(X),"])".

mypr(X) --> "<pred>", atomey(F), {\+end_tag(F)}, mypr(arg(A)), "</pred>", {append([F],A,FL),X=..FL}.
mypr(arg(A)) --> "<arg>", mypr(Arg), "</arg>", mypr(arg(Z)), {append([Arg],Z,A)}.
mypr(arg([])) --> "". 
mypr(X) --> "<atom>", atomey(X), "</atom>".
mypr(X) --> "<var>", atomey(X), "</var>".


atomey(Z) --> [C], {name(Z,[C])}.
atomey(Z) --> %[C], {\+[C]="<"}, 
	atomey(D), [C], {name(H,[C]), atom_concat(D,H,Z)}.
%atomey(Z) --> [C], {name(Z,[C]), \+Z='<'}.
atomey('') --> "".


get_mcontentt(IXM,Content,symbol):-
	get_env(IXM,'symbol',_,[Content|_]).
get_mcontentt(IXM,Content,string):-
	get_env(IXM,'string',_,[Content|_]).
get_mcontentt(IXM,Content,item-var):-
	get_env(IXM,'item-var',_,[Content|_]).
%get_mcontentt(IXM,Content,integer):-
%	get_env(IXM,'integer',_,[Content|_]).
get_mcontentt(IXM,Content,long):-
	get_env(IXM,'long',_,[Content|_]).
% if 'list' then recursive...
get_mcontentt(IXM,Content,list):-
	get_env(IXM,'list',_,[Content|_]).


