module RemsimClient_Tests {

/* Integration Tests for osmo-remsim-client
 * (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-client by attaching to the external interfaces.
 */

import from Osmocom_Types all;
import from IPA_Emulation all;

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

type component client_test_CT extends rspro_server_CT {
	var ComponentIdentity g_srv_comp_id, g_bankd_comp_id;
};

private function f_init() runs on client_test_CT {
	g_srv_comp_id := valueof(ts_CompId(remsimServer, "ttcn-server"));
	g_bankd_comp_id := valueof(ts_CompId(remsimBankd, "ttcn-bankd"));

	f_rspro_srv_init(0, mp_server_ip, mp_server_port, g_srv_comp_id);
	f_rspro_srv_init(1, mp_bankd_ip, mp_bankd_port, g_bankd_comp_id, exp_connect := false);
}


/* ConnectClientReq from client to remsim-server */
testcase TC_srv_connectClient() runs on client_test_CT {
	f_init();
	/* expect inbound connectClientReq */
	as_connectClientReq();
	setverdict(pass);
	f_sleep(1.0);
}

/* ConnectClientReq from client to remsim-server */
testcase TC_srv_connectClient_reject() runs on client_test_CT {
	f_init();
	/* expect inbound connectClientReq */
	as_connectClientReq(res := illegalClientId);
	/* expect disconnect by client */
	RSPRO_SRV[0].receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_DOWN));
	setverdict(pass);
	f_sleep(1.0);
}

/* ConnectClientReq from client to remsim-server */
testcase TC_srv_connectClient_configClientBank() runs on client_test_CT {
	var BankSlot bslot := { 1, 0 };
	f_init();
	/* expect inbound connectClientReq */
	as_connectClientReq();
	/* configure client to connect to [simulated] bankd */
	f_rspro_config_client_bank(bslot, ts_IpPort(ts_IPv4(mp_bankd_ip), mp_bankd_port));
	/* expect inbound connect on simulated bankd */
	f_rspro_srv_exp_connect(1);
	/* expect inbound connectClientReq on simulated bankd */
	as_connectClientReq(i := 1);
	setverdict(pass);
	f_sleep(1.0);
}

/* Test if client re-connects to server after connection is lost */
testcase TC_srv_reconnect() runs on client_test_CT {
	var BankSlot bslot := { 1, 0 };
	f_init();
	/* expect inbound connectClientReq */
	as_connectClientReq();

	/* disconnect the client from server and expect re-establish + re-connect */
	f_rspro_srv_fini(0);
	f_rspro_srv_init(0, mp_server_ip, mp_server_port, g_srv_comp_id, exp_connect := true);
	/* expect inbound connectClientReq */
	as_connectClientReq(i := 0);

	setverdict(pass);
	f_sleep(1.0);
}

/* Test if client re-connects to bank after connection is lost */
testcase TC_bank_reconnect() runs on client_test_CT {
	var BankSlot bslot := { 1, 0 };
	f_init();
	/* expect inbound connectClientReq */
	as_connectClientReq();
	/* configure client to connect to [simulated] bankd */
	f_rspro_config_client_bank(bslot, ts_IpPort(ts_IPv4(mp_bankd_ip), mp_bankd_port));
	/* expect inbound connect on simulated bankd */
	f_rspro_srv_exp_connect(1);
	/* expect inbound connectClientReq on simulated bankd */
	as_connectClientReq(i := 1);

	/* disconnect the client from bankd and expect re-establish + re-connect */
	f_rspro_srv_fini(1);
	f_rspro_srv_init(1, mp_bankd_ip, mp_bankd_port, g_bankd_comp_id, exp_connect := true);
	/* expect inbound connectClientReq on simulated bankd */
	as_connectClientReq(i := 1);

	setverdict(pass);
	f_sleep(1.0);
}

/* TODO:
   * send a configClientBankIpReq and change the bank of an active client
   * send a configClientBankSlotReq and chagne the bank slot of an active client
   * test keepalive mechanism: do we get IPA PING?
   * test keepalive mechanism: do we see disconnect+reconnect if we don't respond to IPA PING?
   * test actual APDU transfers
   * test messages in invalid state, e.g. APDUs before we're connected to a bank
   * test messages on server connection which are only permitted on bankd connection
 */

control {
	execute( TC_srv_connectClient() );
	execute( TC_srv_connectClient_reject() );
	execute( TC_srv_connectClient_configClientBank() );
	execute( TC_srv_reconnect() );
	execute( TC_bank_reconnect() );
}


}
