module RemsimBankd_Tests {

/* Integration Tests for osmo-remsim-bankd
 * (C) 2019 by 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
 *
 * This test suite tests osmo-remsim-bankd by attaching to the external interfaces
 * such as RSPRO for simulated clients + server.
 */

import from Osmocom_Types all;
import from IPA_Emulation all;
import from Misc_Helpers all;

import from VPCD_Types all;
import from VPCD_CodecPort all;
import from VPCD_Adapter all;

import from RSPRO all;
import from RSRES all;
import from RSPRO_Types all;
import from RSPRO_Server all;
import from REMSIM_Tests all;

modulepar {
	integer mp_bank_id := 1;
	integer mp_num_slots := 8;
}

/* We implement a RSPRO server to simulate the remsim-server and a
   RSPRO client to simulate a remsim-client connecting to bankd */
type component bankd_test_CT extends rspro_server_CT, rspro_client_CT, VPCD_Adapter_CT {
	timer g_T_guard := 60.0;
}

private altstep as_Tguard() runs on bankd_test_CT {
	[] g_T_guard.timeout {
		setverdict(fail, "Timeout of T_guard");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
}

private function f_init(boolean start_client := false) runs on bankd_test_CT {
	var ComponentIdentity srv_comp_id := valueof(ts_CompId(remsimServer, "ttcn-server"));

	/* Start the guard timer */
	g_T_guard.start;
	activate(as_Tguard());

	f_rspro_srv_init(0, mp_server_ip, mp_server_port, srv_comp_id);

	if (start_client) {
		f_init_client(0);
	}
}

private function f_init_client(integer i := 0) runs on rspro_client_CT {
	var ComponentIdentity clnt_comp_id := valueof(ts_CompId(remsimClient, "ttcn-client"));
	f_rspro_init(rspro[0], mp_bankd_ip, mp_bankd_port, clnt_comp_id, 0);
	rspro[0].rspro_client_slot := { clientId := 23+i, slotNr := 0 };
}



/* Test if the bankd disconnects the TCP/IPA session if we don't respond to connectBankReq */
testcase TC_connectBankReq_timeout() runs on bankd_test_CT {
	timer T := 20.0;
	f_init();

	f_rspro_srv_exp(tr_RSPRO_ConnectBankReq(?, ?, ?));
	T.start;
	alt {
	[] RSPRO_SRV[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
		setverdict(pass);
		}
	[] RSPRO_SRV[0].receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for disconnect");
		}
	}
}

/* accept an inbound connection from bankd to simulated server */
testcase TC_connectBankReq() runs on bankd_test_CT {
	f_init();

	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* attempt to create a mapping */
testcase TC_createMapping() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	f_rspro_srv_create_slotmap(cs, bs);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* attempt to create a mapping for a slot that already has a mapping */
testcase TC_createMapping_busySlot() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	/* create the mapping the first time */
	f_rspro_srv_create_slotmap(cs, bs);
	/* re-create the mapping a second time */
	f_rspro_srv_create_slotmap(cs, bs);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* attempt to create a mapping for an out-of-range slot number */
testcase TC_createMapping_invalidSlot() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 200 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	f_rspro_srv_create_slotmap(cs, bs, exp_res := illegalSlotId);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* attempt to create a mapping for an invalid bankID */
testcase TC_createMapping_invalidBank() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := 200, slotNr := 0 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	f_rspro_srv_create_slotmap(cs, bs, exp_res := illegalBankId);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* attempt to remove a non-existant mapping */
testcase TC_removeMapping_unknownMap() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	f_rspro_srv_remove_slotmap(cs, bs, exp_res := unknownSlotmap);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* add and then remove a mapping, expect both to be successful */
testcase TC_removeMapping() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	f_rspro_srv_create_slotmap(cs, bs);
	f_rspro_srv_remove_slotmap(cs, bs);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* connect from client to bankd without specifying a clientId */
testcase TC_clientConnect_missingSlot() runs on bankd_test_CT {
	f_init_client(0);
	RSPRO[0].send(ts_RSPRO_ConnectClientReq(rspro[0].rspro_id, omit));
	f_rspro_exp(tr_RSPRO_ConnectClientRes(?, ResultCode:illegalClientId), 0);
	f_rspro_exp_disconnect(0);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* connect from client to bankd using a clientId for which bankd has no map */
testcase TC_clientConnect_unknown() runs on bankd_test_CT {
	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* connect from client to bankd using a clientSlot for which bankd has no map */


/* first connect client, then later add matching mapping from server */
testcase TC_clientConnect_createMapping() runs on bankd_test_CT {
	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);

	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
	f_sleep(10.0);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}


/* first add mapping, then connect matching client */
testcase TC_createMapping_clientConnect() runs on bankd_test_CT {
	/* FIXME: this would only be done in f_init_client(), but we need it before */
	rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);

	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	f_sleep(1.0);

	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* FIXME: how to determine that bank correctly mapped us */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* first add mapping, then connect client, then change mapping (expect disconnect) */
testcase TC_createMapping_connectClient_changeMapping() runs on bankd_test_CT {
	/* FIXME: this would only be done in f_init_client(), but we need it before */
	rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);

	/* create slotmap */
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	f_sleep(1.0);

	/* connect client */
	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* FIXME: how to determine that bank correctly mapped us */

	/* create another mapping for the same bank-slot */
	var ClientSlot cs := { clientId := 987, slotNr := 654 };
	f_rspro_srv_create_slotmap(cs, bs);

	/* expect client to be disconnected */
	timer T := 5.0;
	T.start;
	alt {
	[] RSPRO[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
		setverdict(pass);
		}
	[] RSPRO[0].receive {
		setverdict(fail, "Unexpected RSPRO on client connection");
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for client being disconnected");
		}
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* first add mapping, then connect client, then re-crete mapping (expect no disconnect) */
testcase TC_createMapping_connectClient_recreateMapping() runs on bankd_test_CT {
	/* FIXME: this would only be done in f_init_client(), but we need it before */
	rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);

	/* create slotmap */
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	f_sleep(1.0);

	/* connect client */
	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* FIXME: how to determine that bank correctly mapped us */

	/* re-create same mapping for the same bank-slot */
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	/* expect client not to be disconnected */
	timer T := 5.0;
	T.start;
	alt {
	[] RSPRO[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
		setverdict(fail, "Unexpected client disconnect");
		}
	[] RSPRO[0].receive {
		repeat;
		}
	[] T.timeout {
		setverdict(pass);
		}
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}



/* add mapping, connect matching client, disconnect + reconnect */
testcase TC_createMapping_clientReconnect() runs on bankd_test_CT {
	/* FIXME: this would only be done in f_init_client(), but we need it before */
	rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);

	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	f_sleep(1.0);

	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* TODO: works only with empty slot, as setAtrReq isn't handled */
	/* FIXME: how to determine that bank correctly mapped us */
	f_sleep(5.0);
	f_rspro_fini(rspro[0], 0);

	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* FIXME: how to determine that bank correctly mapped us */
	f_sleep(5.0);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}



/* remove mapping while client is connected */
testcase TC_removeMapping_connected() runs on bankd_test_CT {
	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* TODO: works only with empty slot, as setAtrReq isn't handled */

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);

	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
	/* FIXME: how to determine that bank correctly mapped us */
	f_sleep(5.0);
	f_rspro_srv_remove_slotmap(rspro[0].rspro_client_slot, bs);
	f_rspro_exp_disconnect(0);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

private altstep as_vpcd() runs on VPCD_Adapter_CT {
	[] VPCD.receive(tr_VPCD_Recv(g_vpcd_conn_id, tr_VPCD_CTRL_ATR)) {
		f_vpcd_send(ts_VPCD_DATA('3B9F96801FC78031A073BE21136743200718000001A5'O));
		repeat;
		}
	[] VPCD.receive(tr_VPCD_Recv(g_vpcd_conn_id, tr_VPCD_CTRL_OFF)) {
		repeat;
		}
	[] VPCD.receive(tr_VPCD_Recv(g_vpcd_conn_id, tr_VPCD_CTRL_ON)) {
		repeat;
		}
}

/* transceive a TPDU from modem to card (and back) */
function f_rspro_xceive_mdm2card_vpcd(integer idx, BankSlot bs, template (value) octetstring data,
				 template (value) TpduFlags flags, template (value) octetstring res) runs on bankd_test_CT return octetstring {
	var RsproPDU rx;
	RSPRO[idx].send(ts_RSPRO_TpduModemToCard(rspro[idx].rspro_client_slot, bs, flags, data));
	f_vpcd_exp(tr_VPCD_DATA(data));
	f_vpcd_send(ts_VPCD_DATA(res));
	rx := f_rspro_exp(tr_RSPRO_TpduCardToModem(bs, rspro[idx].rspro_client_slot, ?, ?));
	if (rx.msg.tpduCardToModem.data != valueof(res)) {
		setverdict(fail, "Expected ", res, " from card, but got ", rx.msg.tpduCardToModem.data);
	}
	return rx.msg.tpduCardToModem.data;
}


/* first add mapping, then connect matching client and exchange some TPDUs */
testcase TC_createMapping_exchangeTPDU() runs on bankd_test_CT {
	/* FIXME: this would only be done in f_init_client(), but we need it before */
	rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };

	VPCD_Adapter.f_connect();
	activate(as_vpcd());
	f_sleep(2.0);

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);

	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	f_sleep(1.0);

	f_init_client(0);
	f_rspro_connect_client(0, ok);
	/* FIXME: how to determine that bank correctly mapped us */
	f_rspro_exp(tr_RSPRO_SetAtrReq(rspro[0].rspro_client_slot, ?));

	var TpduFlags f := {tpduHeaderPresent:=true, finalPart:=true, procByteContinueTx:=false,
			    procByteContinueRx:=false};
	for (var integer i := 0; i < 10; i:=i+1) {
		f_rspro_xceive_mdm2card_vpcd(0, bs, 'A0A40000023F00'O, f, '9000'O);
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}



control {
	execute( TC_connectBankReq_timeout() );
	execute( TC_connectBankReq() );

	execute( TC_createMapping() );
	execute( TC_createMapping_busySlot() );
	execute( TC_createMapping_invalidSlot() );
	execute( TC_createMapping_invalidBank() );

	execute( TC_removeMapping_unknownMap() );
	execute( TC_removeMapping() );

	execute( TC_clientConnect_missingSlot() );
	execute( TC_clientConnect_unknown() );
	execute( TC_clientConnect_createMapping() );
	execute( TC_createMapping_clientConnect() );
	execute( TC_createMapping_clientReconnect() );
	execute( TC_removeMapping_connected() );

	execute( TC_createMapping_connectClient_changeMapping() );
	execute( TC_createMapping_connectClient_recreateMapping() );

	execute( TC_createMapping_exchangeTPDU() );
}





}
