/* PFCP Emulation in TTCN-3
 *
 * (C) 2022 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

module PFCP_Emulation {

import from IPL4asp_Types all;
import from General_Types all;
import from Osmocom_Types all;
import from PFCP_Types all;
import from PFCP_CodecPort all;
import from PFCP_CodecPort_CtrlFunct all;

/***********************************************************************
 * Main Emulation Component
 ***********************************************************************/

const integer PFCP_PORT := 8805;

type enumerated PFCP_Role {
	CPF,
	UPF
};

type record PFCP_Emulation_Cfg {
	HostName pfcp_bind_ip,
	PortNumber pfcp_bind_port,
	HostName pfcp_remote_ip,
	PortNumber pfcp_remote_port,
	PFCP_Role role
};

type component PFCP_Emulation_CT {
	/* Communication with underlying PFCP CodecPort */
	port PFCP_PT PFCP;

	/* Communication with Clients */
	port PFCPEM_PT CLIENT;
	port PFCPEM_PROC_PT CLIENT_PROC;

	/* Configuration by the user */
	var PFCP_Emulation_Cfg g_pfcp_cfg;

	/* State */
	var integer g_pfcp_conn_id;
	var integer g_recovery_timestamp;

	var PFCPEM_conns g_conns;

	var integer g_next_sequence_nr_state;
};

private function f_PFCPEM_next_sequence_nr() runs on PFCP_Emulation_CT return integer {
	g_next_sequence_nr_state := g_next_sequence_nr_state + 1;
	if (g_next_sequence_nr_state > 16777215) {
		g_next_sequence_nr_state := 1;
	}
	return g_next_sequence_nr_state;
}

type record PFCPEM_conn {
	PFCP_ConnHdlr vc_conn,
	OCT8 seid optional,
	LIN3_BO_LAST pfcp_msg_sequence_number optional
};

type record of PFCPEM_conn PFCPEM_conns;

private function f_PFCPEM_conn_by_seid_or_seqnr(OCT8 seid, LIN3_BO_LAST seqnr) runs on PFCP_Emulation_CT return PFCP_ConnHdlr {
	log("looking for seid ", seid, " seqnr ", seqnr, " in conns ", g_conns);
	for (var integer i := 0; i < lengthof(g_conns); i := i + 1) {
		if (isbound(g_conns[i].pfcp_msg_sequence_number)
		    and seqnr == g_conns[i].pfcp_msg_sequence_number) {
			return g_conns[i].vc_conn;
		}
		if (isbound(g_conns[i].seid)
		    and seid == g_conns[i].seid) {
			return g_conns[i].vc_conn;
		}
	}
	return null;
};

private function f_PFCPEM_add_conn(PFCP_ConnHdlr vc_conn) runs on PFCP_Emulation_CT {
	for (var integer i := 0; i < lengthof(g_conns); i := i + 1) {
		if (g_conns[i].vc_conn == vc_conn) {
			return;
		}
	}
	/* Not in the list yet, add. */
	var PFCPEM_conn conn := { vc_conn := vc_conn };
	g_conns := g_conns & { conn };
}

private function f_init(PFCP_Emulation_Cfg cfg) runs on PFCP_Emulation_CT {
	var Result res;

	map(self:PFCP, system:PFCP);
	res := PFCP_CodecPort_CtrlFunct.f_IPL4_listen(PFCP, cfg.pfcp_bind_ip, cfg.pfcp_bind_port, {udp:={}});
	g_pfcp_conn_id := res.connId;

	g_recovery_timestamp := f_rnd_int(4294967296);
	g_pfcp_cfg := cfg;

	g_conns := {};

	g_next_sequence_nr_state := (1 + f_rnd_int(1000)) * 10000;
}

function main(PFCP_Emulation_Cfg cfg) runs on PFCP_Emulation_CT {
	var PFCP_ConnHdlr vc_conn;
	var PFCP_Unitdata ud;
	var PDU_PFCP pdu;

	f_init(cfg);

	while (true) {
		alt {
		[] PFCP.receive(PFCP_Unitdata:?) -> value ud {
				log("PFCP_Emulation main() PFCP.receive: ", ud);
				vc_conn := null;
				if (ud.pdu.s_flag == '1'B) {
					/* There is a SEID */
					vc_conn := f_PFCPEM_conn_by_seid_or_seqnr(ud.pdu.seid, ud.pdu.sequence_number);
				}
				if (vc_conn != null) {
					log("found destination ", vc_conn);
					CLIENT.send(ud.pdu) to vc_conn;
				} else {
					log("sending to all conns: ", g_conns);
					for (var integer i := 0; i < lengthof(g_conns); i := i + 1) {
						CLIENT.send(ud.pdu) to g_conns[i].vc_conn;
					}
				}
			}

		[] CLIENT.receive(PDU_PFCP:?) -> value pdu sender vc_conn {
				log("PFCP_Emulation main() CLIENT.receive from ", vc_conn, ": ", pdu);
				if (pdu.sequence_number == 0) {
					pdu.sequence_number := f_PFCPEM_next_sequence_nr();
				}
				ud := {
					peer := {
						conn_id := g_pfcp_conn_id,
						remote_name := g_pfcp_cfg.pfcp_remote_ip,
						remote_port := g_pfcp_cfg.pfcp_remote_port
					},
					pdu := pdu
				};

				f_PFCPEM_add_conn(vc_conn);

				PFCP.send(ud);
			}

		[] CLIENT_PROC.getcall(PFCPEM_register:{}) -> sender vc_conn {
				log("PFCP_Emulation main() CLIENT_PROC.getcall(PFCPEM_register)");
				f_PFCPEM_add_conn(vc_conn);
				CLIENT_PROC.reply(PFCPEM_register:{}) to vc_conn;
			}
		}
	}
}


/***********************************************************************
 * Interaction between Main and Client Components
 ***********************************************************************/
type port PFCPEM_PT message {
	inout PDU_PFCP;
} with { extension "internal" };

signature PFCPEM_register();

type port PFCPEM_PROC_PT procedure {
	inout PFCPEM_register;
} with { extension "internal" };

/***********************************************************************
 * Client Component
 ***********************************************************************/

type component PFCP_ConnHdlr {
	port PFCPEM_PT PFCP;
	port PFCPEM_PROC_PT PFCP_PROC;
	var PFCP_Emulation_CT vc_PFCP;
};

function f_pfcp_register() runs on PFCP_ConnHdlr {
	PFCP_PROC.call(PFCPEM_register:{}) {
		[] PFCP_PROC.getreply(PFCPEM_register:{});
	}
}

}
