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;
}

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 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:={} });
	
	
	while (true) {
		alt {
		[] CLIENT.receive(MgcpCommand:?) {
			}
		[] MGCP.receive(MGCP_RecvFrom:?) {
			}
		[] PROC.getcall(MGCPEM_register:{?,?}) -> param(crit, vc_conn) {
			f_create_expect(crit, vc_conn);
			PROC.reply(MGCPEM_register:{crit, vc_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;
	}
}

}
