module MME_Tests_SGsAP {

/* Osmocom MME test suite in in TTCN-3
 * (C) 2019 Harald Welte <laforge@gnumonks.org>
 * 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
 */

import from SGsAP_Types all;
import from SGsAP_Templates all;
import from SGsAP_Emulation all;

import from General_Types all;
import from Osmocom_Types all;
import from L3_Templates all;
import from DNS_Helpers all;
import from MME_Tests all;

/* performa SGs reset procedure */
function f_sgsap_vlr_reset() runs on ConnHdlr {
	var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
	var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);

	SGsAP.send(ts_SGsAP_RESET_IND_VLR(vlr_name));
	alt {
	[] SGsAP.receive(tr_SGsAP_RESET_ACK(mme_name, vlr_name)) {
		setverdict(pass);
		}
	[] SGsAP.receive(tr_SGsAP_RESET_ACK(?, ?)) {
		setverdict(fail, "Received unexpected VLR/MME name in SGsAP RESET ACK");
		}
	[] SGsAP.receive {
		setverdict(fail, "Received unexpected response to SGsAP RESET");
		}
	}
}

/* perform a SGs paging procedure */
function f_sgsap_page(Service_Indicator serv_ind, template (omit) OCT4 tmsi,
			template (omit) SGs_Cause exp_cause) runs on ConnHdlr {
	var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
	var boolean exp_success := true;
	var PDU_SGsAP rx;
	if (not istemplatekind(exp_cause, "omit")) {
		exp_success := false;
	}
	SGsAP.send(ts_SGsAP_PAGING_REQ(g_pars.ue_pars.imsi, vlr_name, serv_ind, tmsi));
	alt {
	/* we expect success */
	[exp_success] SGsAP.receive(tr_SGsAP_SERVICE_REQ(g_pars.ue_pars.imsi, serv_ind, ?)) {
		setverdict(pass);
		}
	[exp_success] SGsAP.receive(tr_SGsAP_PAGING_REJ(g_pars.ue_pars.imsi, ?)) {
		setverdict(fail, "Received unexpected PAGING REJECT");
		}
	/* we expect failure */
	[not exp_success] SGsAP.receive(tr_SGsAP_SERVICE_REQ(g_pars.ue_pars.imsi, serv_ind, ?)) {
		setverdict(fail, "Received SERVICE REQ waiting for PAGING REJECT");
		}
	[not exp_success] SGsAP.receive(tr_SGsAP_PAGING_REJ(g_pars.ue_pars.imsi, exp_cause)) {
		setverdict(pass);
		}
	[not exp_success] SGsAP.receive(tr_SGsAP_PAGING_REJ(g_pars.ue_pars.imsi, ?)) {
		setverdict(fail, "Received unexpected PAGING REJECT cause");
		}
	[] SGsAP.receive {
		setverdict(fail, "Received unexpected SgSAP");
		}
	}
}

/* perform a SGs alert procedure */
function f_sgsap_alert(template (omit) SGs_Cause exp_cause) runs on ConnHdlr{
	var boolean exp_success := true;
	var PDU_SGsAP rx;
	if (not istemplatekind(exp_cause, "omit")) {
		exp_success := false;
	}
	SGsAP.send(ts_SGsAP_ALERT_REQ(g_pars.ue_pars.imsi));
	alt {
	[exp_success] SGsAP.receive(tr_SGsAP_ALERT_ACK(g_pars.ue_pars.imsi)) {
		setverdict(pass);
		}
	[exp_success] SGsAP.receive(tr_SGsAP_ALERT_REJECT(g_pars.ue_pars.imsi, ?)) -> value rx {
		setverdict(fail, "Received unexpected ALERT REJECT ", rx);
		}
	[not exp_success] SGsAP.receive(tr_SGsAP_ALERT_ACK(g_pars.ue_pars.imsi)) {
		setverdict(fail, "Received unexpected ALERT ACK");
		}
	[not exp_success] SGsAP.receive(tr_SGsAP_ALERT_REJECT(g_pars.ue_pars.imsi, exp_cause)) {
		setverdict(pass)
		}
	[not exp_success] SGsAP.receive(tr_SGsAP_ALERT_REJECT(g_pars.ue_pars.imsi, ?)) -> value rx {
		setverdict(fail, "Received ALERT REJECT with unexpected cause ", rx);
		}
	[] SGsAP.receive {
		setverdict(fail, "Received unexpected SGsAP");
		}
	}
}

/* Test if MME responds to VLR-originated RESET procedure as expected */
private function f_TC_sgsap_vlr_reset(ConnHdlrPars pars) runs on ConnHdlr {
	f_init_handler(pars);
	f_sgsap_vlr_reset();
}
testcase TC_sgsap_vlr_reset() runs on MTC_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init_sgsap(testcasename());
	pars := f_init_pars(1);
	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_vlr_reset), pars);
	vc_conn.done;
}

/* Page known subscriber for SMS */
private function f_TC_sgsap_paging_sms(ConnHdlrPars pars) runs on ConnHdlr {
	f_init_handler(pars);
	/* TODO: register subscriber on S1 */
	f_sgsap_page(SMS_indicator, omit, omit);
}
testcase TC_sgsap_paging_sms() runs on MTC_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init_sgsap(testcasename());
	pars := f_init_pars(2);
	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_paging_sms), pars);
	vc_conn.done;
}

/* Page known subscriber for CS call */
private function f_TC_sgsap_paging_cs(ConnHdlrPars pars) runs on ConnHdlr {
	f_init_handler(pars);
	/* TODO: register subscriber on S1 */
	f_sgsap_page(CS_call_indicator, omit, omit);
}
testcase TC_sgsap_paging_cs() runs on MTC_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init_sgsap(testcasename());
	pars := f_init_pars(3);
	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_paging_cs), pars);
	vc_conn.done;
}


/* Page unknown subscriber; expect PAGING REJECT from MME */
private function f_TC_sgsap_paging_reject(ConnHdlrPars pars) runs on ConnHdlr {
	f_init_handler(pars);
	f_sgsap_page(SMS_indicator, omit, IMSI_unknown);
}
testcase TC_sgsap_paging_reject() runs on MTC_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init_sgsap(testcasename());
	pars := f_init_pars(4);
	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_paging_reject), pars);
	vc_conn.done;
}

/* Send ALERT-REQ to MME; perform S1AP activity; expect ALERT-ACK on SGs */
private function f_TC_sgsap_alert(ConnHdlrPars pars) runs on ConnHdlr {
	f_init_handler(pars);
	/* TODO: register subscriber on S1 */
	f_sgsap_alert(omit);
	/* TOOD: do something on S1 triggering UE ACT IND */
	SGsAP.receive(tr_SGsAP_UE_ACT_IND(g_pars.ue_pars.imsi));
}
testcase TC_sgsap_alert() runs on MTC_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init_sgsap(testcasename());
	pars := f_init_pars(5);
	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_alert), pars);
	vc_conn.done;
}

/* Send ALERT-REQ to MME for unidentified IMSI; expect ALERT-REJ on SGs */
private function f_TC_sgsap_alert_rej(ConnHdlrPars pars) runs on ConnHdlr {
	f_init_handler(pars);
	/* IMSI doesn't register and is hence unknown */
	f_sgsap_alert(IMSI_unknown);
}
testcase TC_sgsap_alert_rej() runs on MTC_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init_sgsap(testcasename());
	pars := f_init_pars(6);
	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_alert_rej), pars);
	vc_conn.done;
}


/* Test SGsAP-DOWNLINK-UNITDATA (SGs -> S1) */
/* Test SGsAP-UPLINK-UNITDATA (S1 -> SGs)*/
/* Test SGSAP-DETACH-IND; detach on S1; expect DETACH-IND on SGs; send DETACH-ACK */
/* Test SGsAP-LU-REQ; perform combined attach on S1; expect LU-REQ; acknowlege it */
/* Test SGsAP-LU-REQ; perform combined attach on S1; expect LU-REQ; reject it */
/* Test SGsAP-MMINFO-REQ; establish SGs association; send it on SGs; expect on S1 */

/* Test MT SERVICE ABORT; send PAGING; expect SERVICE REQ; send SERVICE ABORT */

/* Test EPS DETACH */
/* Test IMSI DETACH */

}
