module MGCP_Emulation {

import from MGCP_CodecPort all;
import from MGCP_CodecPort_CtrlFunct all;
import from MGCP_Types all;
import from MGCP_Templates all;
import from Osmocom_Types all;
import from IPL4asp_Types all;

type component MGCP_ConnHdlr {
	port MGCP_Conn_PT MGCP;
	var MgcpConnectionId mgcp_conn_id;
}

/* port between individual per-connection components and this dispatcher */
type port MGCP_Conn_PT message {
	inout MgcpCommand, MgcpResponse;
} with { extension "internal" };


type component MGCP_Emulation_CT {
	/* Port facing to the UDP SUT */
	port MGCP_CODEC_PT MGCP;
	/* All MGCP_ConnHdlr MGCP ports connect here
	 * MGCP_Emulation_CT.main needs to figure out what messages
	 * to send where with CLIENT.send() to vc_conn */
	port MGCP_Conn_PT CLIENT;
	/* currently tracked connections */
//	var ConnectionData ConnectionTable[16];
	/* pending expected CRCX */
	var ExpectData ExpectTable[8];
	/* procedure based port to register for incoming connections */
	port MGCPEM_PROC_PT PROC;

	var charstring g_mgcp_id;
	var integer g_mgcp_conn_id := -1;
}

type function MGCPCreateCallback(MgcpCommand cmd, charstring id)
runs on MGCP_Emulation_CT return MGCP_ConnHdlr;

type record MGCPOps {
	MGCPCreateCallback create_cb
}

type record MGCP_conn_parameters {
	charstring callagent_ip,
	uint16_t callagent_udp_port,
	charstring mgw_ip,
	uint16_t mgw_udp_port
}

function tr_MGCP_RecvFrom_R(template MgcpMessage msg)
runs on MGCP_Emulation_CT return template MGCP_RecvFrom {
	var template MGCP_RecvFrom mrf := {
		connId := g_mgcp_conn_id,
		remName := ?,
		remPort := ?,
		locName := ?,
		locPort := ?,
		msg := msg
	}
	return mrf;
}

function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_Emulation_CT {
	var Result res;
	g_mgcp_id := id;
	//f_conn_table_init();
	f_expect_table_init();

	map(self:MGCP, system:MGCP_CODEC_PT);
	res := MGCP_CodecPort_CtrlFunct.f_IPL4_connect(MGCP, p.mgw_ip,
p.mgw_udp_port,
		p.callagent_ip, p.callagent_udp_port, 0, { udp:={} });
	
	g_mgcp_conn_id := res.connId;
	
	while (true) {
		var MGCP_ConnHdlr vc_conn;
		var ExpectCriteria crit;
		var MGCP_RecvFrom mrf;
		var MgcpMessage msg;
		var MgcpCommand cmd;
		var MgcpResponse resp;

		alt {
		/* MGCP from client */
		[] CLIENT.receive(MgcpResponse:?) -> value resp sender vc_conn {
			/* Pass message through */
			msg.response := resp;
			MGCP.send(t_MGCP_Send(g_mgcp_conn_id, msg));
			}
		[] MGCP.receive(tr_MGCP_RecvFrom_R(?)) -> value mrf {
			if (ischosen(mrf.msg.command)) {
				cmd := mrf.msg.command;
				vc_conn := ops.create_cb.apply(cmd, id);
				f_handle_userData(vc_conn, cmd);
			} else {
				setverdict(fail, "Received unexpected MGCP response: ", mrf.msg.response);
				self.stop;
			}
			}
		[] PROC.getcall(MGCPEM_register:{?,?}) -> param(crit, vc_conn) {
			f_create_expect(crit, vc_conn);
			PROC.reply(MGCPEM_register:{crit, vc_conn});
			}
		}
	}
}

private function f_handle_userData(MGCP_ConnHdlr conn, MgcpCommand cmd)
runs on MGCP_Emulation_CT {
	CLIENT.send(cmd) to conn;
}

/* "Expect" Handling */

/*  */
type record ExpectCriteria {
	MgcpConnectionId connid optional,
	MgcpEndpoint endpoint optional,
	MgcpTransId transid optional
}

type record ExpectData {
	ExpectCriteria crit optional,
	MGCP_ConnHdlr vc_conn
}

signature MGCPEM_register(in ExpectCriteria cmd, in MGCP_ConnHdlr hdlr);

type port MGCPEM_PROC_PT procedure {
	inout MGCPEM_register;
} with { extension "internal" };

function f_get_mgcp_by_crit(ExpectCriteria crit)
return template MgcpCommand {
	template MgcpCommand ret := {
	};

	return ret;
}

/* Function that can be used as create_cb and will usse the expect table */
function ExpectedCreateCallback(MgcpCommand cmd, charstring id)
runs on MGCP_Emulation_CT return MGCP_ConnHdlr {
	var MGCP_ConnHdlr ret := null;
	var template MgcpCommand mgcpcmd;
	var integer i;

	/* Ensure cmd is a CRCX? */

	for (i := 0; i < sizeof(ExpectTable); i := i+1) {
		if (not ispresent(ExpectTable[i].crit)) {
			continue;
		}
		/* FIXME: Ignore criteria for now */
//		mgcpcmd := f_get_mgcp_by_crit(ExpectTable[i].crit);
//		if (match(cmd, mgcpcmd)) {
			ret := ExpectTable[i].vc_conn;
			/* Release this entry */
			ExpectTable[i].crit := omit;
			ExpectTable[i].vc_conn := null;
			log("Found Expect[", i, "] for ", cmd, " handled at ", ret);
			return ret;
//		}
	}
	setverdict(fail, "Couldn't find Expect for CRCX", cmd);
	return ret;
}

private function f_create_expect(ExpectCriteria crit, MGCP_ConnHdlr hdlr)
runs on MGCP_Emulation_CT {
	var integer i;

	/* Check an entry like this is not already presnt */
	for (i := 0; i < sizeof(ExpectTable); i := i+1) {
		if (crit == ExpectTable[i].crit) {
			setverdict(fail, "Crit already present", crit);
			self.stop;
		}
	}
	for (i := 0; i < sizeof(ExpectTable); i := i+1) {
		if (not ispresent(ExpectTable[i].crit)) {
			ExpectTable[i].crit := crit;
			ExpectTable[i].vc_conn := hdlr;
			log("Created Expect[", i, "] for ", crit, " to be handled at ", hdlr);
			return;
		}
	}
	setverdict(fail, "No space left in ExpectTable")
}

private function f_expect_table_init()
runs on MGCP_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(ExpectTable); i := i + 1) {
		ExpectTable[i].crit := omit;
	}
}

}
