module RemsimServer_Tests {

/* Integration Tests for osmo-remsim-server
 * (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-server by attaching to the external interfaces
 * such as RSPRO for simulated clients + bankds and RSRES (REST backend interface).
 */

import from Osmocom_Types all;

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

import from Misc_Helpers all;
import from IPA_Emulation all;

import from HTTPmsg_Types all;
import from HTTPmsg_PortType all;
import from HTTP_Adapter all;
import from JSON_Types all;

/* run a HTTP GET on specified URL expecting json in RSRES format as response */
function f_rsres_get(charstring url, template integer exp_sts := 200)
runs on http_CT return JsRoot {
	var HTTPMessage http_resp;
	http_resp := f_http_transact(url, exp := tr_HTTP_Resp(exp_sts));
	return f_dec_JsRoot(char2oct(http_resp.response.body));
}

/* run a HTTP PUT to add a new slotmap to the remsim-server */
function f_rsres_post_slotmap(JsSlotmap slotmap, template integer exp_sts := 201)
runs on http_CT return HTTPResponse {
	var charstring body := oct2char(f_enc_JsSlotmap(slotmap));
	var HTTPMessage http_resp;
	http_resp := f_http_transact(url := "/api/backend/v1/slotmaps", method := "POST",
				     body := body, exp := tr_HTTP_Resp(exp_sts))
	return http_resp.response;
}

/* run a HTTP PUT to add a new slotmap to the remsim-server */
function f_rsres_post_reset(template integer exp_sts := 200)
runs on http_CT return HTTPResponse {
	var HTTPMessage http_resp;
	http_resp := f_http_transact(url := "/api/backend/v1/global-reset", method := "POST",
				     body := "", exp := tr_HTTP_Resp(exp_sts))
	return http_resp.response;
}


/* run a HTTP DELETE to remove a slotmap from te remsim-server */
function f_rsres_delete_slotmap(BankSlot bs, template integer exp_sts := 200)
runs on http_CT return HTTPResponse {
	var HTTPMessage http_resp;
	var integer slotmap_id := bs.bankId * 65536 + bs.slotNr;
	http_resp := f_http_transact(url := "/api/backend/v1/slotmaps/" & int2str(slotmap_id),
				     method := "DELETE", exp := tr_HTTP_Resp(exp_sts));
	return http_resp.response;
}


function f_rsres_init() runs on http_CT {
	var HTTP_Adapter_Params http_adapter_pars;
	http_adapter_pars := {
		http_host := mp_server_ip,
		http_port := mp_rsres_port
	};
	f_http_init(http_adapter_pars);
	f_rsres_post_reset();
}

type component test_CT extends rspro_client_CT, http_CT {
	timer g_T_guard := 60.0;
};

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

private function f_init() runs on test_CT {
	/* Start the guard timer */
	g_T_guard.start;
	activate(as_Tguard());
}


testcase TC_connect_and_nothing() runs on test_CT {
	var ComponentIdentity rspro_id := valueof(ts_CompId(remsimClient, "foobar"));
	timer T := 20.0;

	f_init();
	f_rspro_init(rspro[0], mp_server_ip, mp_server_port, rspro_id, 0);
	T.start;
	/* expect that we're disconnected if we never send a ConnectClientReq */
	alt {
	[] RSPRO[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) { repeat; }
	[] RSPRO[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
		setverdict(pass);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for disconnect");
		}
	}
}

testcase TC_connect_client() runs on test_CT {
	var ComponentIdentity rspro_id := valueof(ts_CompId(remsimClient, "foobar"));
	var JsRoot js;

	f_init();
	f_rsres_init();
	f_rspro_init(rspro[0], mp_server_ip, mp_server_port, rspro_id, 0);
	rspro[0].rspro_client_slot := valueof(ts_ClientSlot(3,4));

	js := f_rsres_get("/api/backend/v1/clients");
	if (not match(js.clients, JsClients:{})) {
		setverdict(fail, "Initial state not empty");
		mtc.stop;
	}
	f_rspro_connect_client(0);
	js := f_rsres_get("/api/backend/v1/clients");
	if (not match(js.clients[0], tr_JsClient(CONNECTED_CLIENT, rspro[0].rspro_id))) {
		setverdict(fail, "Non-matching JSON response");
		mtc.stop;
	}
	//as_rspro_cfg_client_id(0, cslot);
	setverdict(pass);
}

/* duplicate connection from Same Client/Slot ID */
testcase TC_connect_client_duplicate() runs on test_CT {
	var ComponentIdentity rspro_id := valueof(ts_CompId(remsimClient, "foobar"));
	var JsRoot js;

	f_init();
	f_rsres_init();
	f_rspro_init(rspro[0], mp_server_ip, mp_server_port, rspro_id, 0);
	rspro[0].rspro_client_slot := valueof(ts_ClientSlot(13,1));

	js := f_rsres_get("/api/backend/v1/clients");
	if (not match(js.clients, JsClients:{})) {
		setverdict(fail, "Initial state not empty");
		mtc.stop;
	}
	f_rspro_connect_client(0);
	js := f_rsres_get("/api/backend/v1/clients");
	if (not match(js.clients[0], tr_JsClient(CONNECTED_CLIENT, rspro[0].rspro_id))) {
		setverdict(fail, "Non-matching JSON response");
		mtc.stop;
	}

	/* connect a second time for same Client ID */
	f_rspro_init(rspro[1], mp_server_ip, mp_server_port, rspro_id, 1);
	rspro[1].rspro_client_slot := valueof(ts_ClientSlot(13,1));
	f_rspro_connect_client(1, identityInUse);
	f_rspro_exp_disconnect(1);

	/* expect the first connection still to be active */
	js := f_rsres_get("/api/backend/v1/clients");
	if (not match(js.clients[0], tr_JsClient(CONNECTED_CLIENT, rspro[0].rspro_id))) {
		setverdict(fail, "Non-matching JSON response");
		mtc.stop;
	}

	setverdict(pass);
}

testcase TC_connect_bank() runs on test_CT {
	var ComponentIdentity rspro_id := valueof(ts_CompId(remsimBankd, "foobar"));
	var JsRoot js;

	f_init();
	f_rsres_init();
	f_rspro_init(rspro[0], mp_server_ip, mp_server_port, rspro_id, 0);
	rspro[0].rspro_bank_id := 1;
	rspro[0].rspro_bank_nslots := 8;

	js := f_rsres_get("/api/backend/v1/banks");
	if (not match(js.banks, JsBanks:{})) {
		setverdict(fail, "Initial state not empty");
		mtc.stop;
	}
	f_rspro_connect_client(0);
	js := f_rsres_get("/api/backend/v1/banks");
	if (not match(js.banks[0], tr_JsBank(CONNECTED_BANKD, rspro[0].rspro_id, rspro[0].rspro_bank_id,
					     rspro[0].rspro_bank_nslots))) {
		setverdict(fail, "Non-matching JSON response");
		mtc.stop;
	}
	setverdict(pass);
}

testcase TC_connect_bank_duplicate() runs on test_CT {
	var ComponentIdentity rspro_id := valueof(ts_CompId(remsimBankd, "foobar"));
	var JsRoot js;

	f_init();
	f_rsres_init();
	f_rspro_init(rspro[0], mp_server_ip, mp_server_port, rspro_id, 0);
	rspro[0].rspro_bank_id := 1;
	rspro[0].rspro_bank_nslots := 8;

	js := f_rsres_get("/api/backend/v1/banks");
	if (not match(js.banks, JsBanks:{})) {
		setverdict(fail, "Initial state not empty");
		mtc.stop;
	}
	f_rspro_connect_client(0);
	js := f_rsres_get("/api/backend/v1/banks");
	if (not match(js.banks[0], tr_JsBank(CONNECTED_BANKD, rspro[0].rspro_id, rspro[0].rspro_bank_id,
					     rspro[0].rspro_bank_nslots))) {
		setverdict(fail, "Non-matching JSON response");
		mtc.stop;
	}

	/* connect a second time for same Bank ID */
	f_rspro_init(rspro[1], mp_server_ip, mp_server_port, rspro_id, 1);
	rspro[1].rspro_bank_id := 1;
	rspro[1].rspro_bank_nslots := 23;
	f_rspro_connect_client(1, identityInUse);

	/* expect only the first bank to survive */
	js := f_rsres_get("/api/backend/v1/banks");
	if (not match(js.banks[0], tr_JsBank(CONNECTED_BANKD, rspro[0].rspro_id, rspro[0].rspro_bank_id,
					     rspro[0].rspro_bank_nslots))) {
		setverdict(fail, "Non-matching JSON response");
		mtc.stop;
	}

	/* wait for T2/rejected timer to expire in server */
	f_sleep(2.0);

	setverdict(pass);
}


function f_ensure_slotmaps(template JsSlotmaps maps)
runs on http_CT {
	var JsRoot js;

	/* check that it is actually added */
	js := f_rsres_get("/api/backend/v1/slotmaps");
	if (match(js.slotmaps, maps)) {
		setverdict(pass);
	} else {
		setverdict(fail, "Unexpected slotmaps: ", js);
	}
}

/* verify that exactly only one slotmap exists (the specified one) */
function f_ensure_slotmap_exists_only(template ClientSlot cslot, template BankSlot bslot,
					template SlotmapState state := ?)
runs on http_CT {
	f_ensure_slotmaps({ tr_JsSlotmap(bslot, cslot, state) } );
}

/* verify that exactly only one slotmap exists (possibly among others) */
function f_ensure_slotmap_exists(template ClientSlot cslot, template BankSlot bslot,
				 template SlotmapState state := ?)
runs on http_CT {
	f_ensure_slotmaps({ *, tr_JsSlotmap(bslot, cslot, state), * } );
}


/* test adding a single slotmap */
testcase TC_slotmap_add() runs on test_CT {
	f_init();
	f_rsres_init();

	var JsSlotmap sm := valueof(ts_JsSlotmap(ts_BankSlot(1,2), ts_ClientSlot(3,4)));
	var HTTPResponse res := f_rsres_post_slotmap(sm);

	/* check that it is actually added */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, NEW);
}

/* test adding a single slotmap with out-of-range values */
testcase TC_slotmap_add_out_of_range() runs on test_CT {
	f_init();
	f_rsres_init();

	var HTTPMessage http_resp;
	var charstring body;

	body := "{ \"bank\": { \"bankId\": 10000, \"slotNr\": 2 }, \"client\": { \"clientId\": 3, \"slotNr\": 4 } }";
	http_resp := f_http_transact(url := "/api/backend/v1/slotmaps", method := "POST",
				     body := body, exp := tr_HTTP_Resp(400));

	body := "{ \"bank\": { \"bankId\": 100, \"slotNr\": 2000 }, \"client\": { \"clientId\": 3, \"slotNr\": 4 } }";
	http_resp := f_http_transact(url := "/api/backend/v1/slotmaps", method := "POST",
				     body := body, exp := tr_HTTP_Resp(400));

	body := "{ \"bank\": { \"bankId\": 100, \"slotNr\": 2 }, \"client\": { \"clientId\": 3000, \"slotNr\": 4 } }";
	http_resp := f_http_transact(url := "/api/backend/v1/slotmaps", method := "POST",
				     body := body, exp := tr_HTTP_Resp(400));

	body := "{ \"bank\": { \"bankId\": 100, \"slotNr\": 2 }, \"client\": { \"clientId\": 3, \"slotNr\": 4000 } }";
	http_resp := f_http_transact(url := "/api/backend/v1/slotmaps", method := "POST",
				     body := body, exp := tr_HTTP_Resp(400));
}


/* test adding a slotmap and then connecting a client + bankd */
testcase TC_slotmap_add_conn_cl_b() runs on test_CT {
	f_init();

	/* Simulate one client */
	var ComponentIdentity rspro_id := valueof(ts_CompId(remsimClient, testcasename()));
	f_rspro_init(rspro[0], mp_server_ip, mp_server_port, rspro_id, 0);
	rspro[0].rspro_client_slot := valueof(ts_ClientSlot(3,4));

	/* Simulate one bankd */
	var BankSlot bslot := valueof(ts_BankSlot(1,2));
	var ComponentIdentity rspro_bank_id := valueof(ts_CompId(remsimBankd, testcasename()));
	f_rspro_init(rspro[1], mp_server_ip, mp_server_port, rspro_bank_id, 1);
	rspro[1].rspro_bank_id := bslot.bankId;
	rspro[1].rspro_bank_nslots := 8

	f_rsres_init();
	var JsSlotmap sm := valueof(ts_JsSlotmap(bslot, rspro[0].rspro_client_slot));
	var HTTPResponse res;

	/* 1) Create a new slotmap via HTTP */
	res := f_rsres_post_slotmap(sm);

	/* 2) verify that the slotmap exists and is NEW */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, NEW);

	/* 3) connect a client for that slotmap */
	f_rspro_connect_client(0);

	/* 4) connect a bankd for that slotmap */
	f_rspro_connect_client(1);

	/* 5) verify that the slotmap exists and is UNACKNOWLEDGED */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, UNACKNOWLEDGED);

	/* 6) expect bankd to receive that mapping */
	as_rspro_create_mapping(1, sm.client, sm.bank);

	/* 7) verify that the slotmap exists and is ACTIVE */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, ACTIVE);

	/* 8) expect the client to be configured with bankd side settings */
	as_rspro_cfg_client_bank(0, bslot, ?);
}

/* test connecting a client and later adding a slotmap for it */
testcase TC_conn_cl_b_slotmap_add() runs on test_CT {
	f_init();

	/* Simulate one client */
	var ComponentIdentity rspro_id := valueof(ts_CompId(remsimClient, testcasename()));
	f_rspro_init(rspro[0], mp_server_ip, mp_server_port, rspro_id, 0);
	rspro[0].rspro_client_slot := valueof(ts_ClientSlot(3,4));

	/* Simulate one bankd */
	var BankSlot bslot := valueof(ts_BankSlot(1,2));
	var ComponentIdentity rspro_bank_id := valueof(ts_CompId(remsimBankd, testcasename()));
	f_rspro_init(rspro[1], mp_server_ip, mp_server_port, rspro_bank_id, 1);
	rspro[1].rspro_bank_id := bslot.bankId;
	rspro[1].rspro_bank_nslots := 8

	f_rsres_init();
	var JsSlotmap sm := valueof(ts_JsSlotmap(bslot, rspro[0].rspro_client_slot));
	var HTTPResponse res;

	/* 1) connect a client for that slotmap */
	f_rspro_connect_client(0);

	/* 2) Create a new slotmap via HTTP */
	res := f_rsres_post_slotmap(sm);

	/* 3) verify that the slotmap exists and is NEW */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, NEW);

	/* 4) connect a bankd for that slotmap */
	f_rspro_connect_client(1);

	/* 5) verify that the slotmap exists and is UNACKNOWLEDGED */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, UNACKNOWLEDGED);

	/* 6) expect bankd to receive that mapping */
	as_rspro_create_mapping(1, sm.client, sm.bank);

	/* 7) verify that the slotmap exists and is ACTIVE */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, ACTIVE);

	/* 8) expect the client to be configured with bankd IP/port */
	as_rspro_cfg_client_bank(0, bslot, ?);
}

/* simple delete of a 'NEW' slotmap */
testcase TC_slotmap_del_new() runs on test_CT {
	f_init();
	f_rsres_init();

	var JsSlotmap sm := valueof(ts_JsSlotmap(ts_BankSlot(1,2), ts_ClientSlot(3,4)));
	var HTTPResponse res := f_rsres_post_slotmap(sm);
	log(res);
	res := f_rsres_delete_slotmap(sm.bank);
	log(res);
}

/* simple delete of a non-existant slotmap */
testcase TC_slotmap_del_nonexistant() runs on test_CT {
	f_init();
	f_rsres_init();

	var JsSlotmap sm := valueof(ts_JsSlotmap(ts_BankSlot(11,12), ts_ClientSlot(13,14)));
	var HTTPResponse res := f_rsres_delete_slotmap(sm.bank, exp_sts:=404);
	log(res);
}


/* simple delete of a 'UNACKNOWLEDGED' slotmap */
testcase TC_slotmap_del_unack() runs on test_CT {
	var ComponentIdentity rspro_id := valueof(ts_CompId(remsimBankd, testcasename()));

	f_init();
	f_rspro_init(rspro[0], mp_server_ip, mp_server_port, rspro_id, 0);
	rspro[0].rspro_bank_id := 1;
	rspro[0].rspro_bank_nslots := 8;

	f_rsres_init();
	var JsSlotmap sm := valueof(ts_JsSlotmap(ts_BankSlot(1,2), ts_ClientSlot(3,4)));
	var HTTPResponse res;

	/* Create a new slotmap via HTTP */
	res := f_rsres_post_slotmap(sm);

	/* verify that the slotmap exists and is NEW */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, NEW);

	/* connect a bankd for that slotmap */
	f_rspro_connect_client(0);

	/* expect the slotmap to be pushed to bank but don't ACK it */
	f_rspro_exp(tr_RSPRO_CreateMappingReq(sm.client, sm.bank));

	/* verify that the slotmap exists and is UNACKNOWLEDGED */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, UNACKNOWLEDGED);

	/* delete the slotmap via REST */
	res := f_rsres_delete_slotmap(sm.bank);

	/* verify the slotmap is gone */
	f_ensure_slotmaps({});
}

/* simple delete of a 'ACTIVE' slotmap from server + bankd */
testcase TC_slotmap_del_active() runs on test_CT {
	var ComponentIdentity rspro_id := valueof(ts_CompId(remsimBankd, testcasename()));

	f_init();
	f_rspro_init(rspro[0], mp_server_ip, mp_server_port, rspro_id, 0);
	rspro[0].rspro_bank_id := 1;
	rspro[0].rspro_bank_nslots := 8;

	f_rsres_init();
	var JsSlotmap sm := valueof(ts_JsSlotmap(ts_BankSlot(1,2), ts_ClientSlot(3,4)));
	var HTTPResponse res;

	/* Create a new slotmap via HTTP */
	res := f_rsres_post_slotmap(sm);

	/* verify that the slotmap exists and is NEW */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, NEW);

	/* connect a bankd for that slotmap */
	f_rspro_connect_client(0);

	/* expect the slotmap to be pushed to bank and ACK it */
	as_rspro_create_mapping(0, sm.client, sm.bank);

	/* verify that the slotmap exists and is ACTIVE */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, ACTIVE);

	f_sleep(1.0);

	/* delete the slotmap via REST */
	res := f_rsres_delete_slotmap(sm.bank);

	/* verify the slotmap is gone from REST interface immediately */
	f_ensure_slotmaps({});

	/* verify the slotmap is removed from bankd */
	as_rspro_remove_mapping(0, sm.client, sm.bank);
}


/* simple delete of a 'ACTIVE' slotmap from client */
testcase TC_slotmap_del_active_client() runs on test_CT {
	var ComponentIdentity rspro_id := valueof(ts_CompId(remsimBankd, testcasename()));

	f_init();
	f_rspro_init(rspro[0], mp_server_ip, mp_server_port, rspro_id, 0);
	rspro[0].rspro_bank_id := 1;
	rspro[0].rspro_bank_nslots := 8;

	rspro_id := valueof(ts_CompId(remsimClient, testcasename()));
	f_rspro_init(rspro[1], mp_server_ip, mp_server_port, rspro_id, 1);
	rspro[1].rspro_client_slot := valueof(ts_ClientSlot(3,4));

	f_rsres_init();
	var JsSlotmap sm := valueof(ts_JsSlotmap(ts_BankSlot(1,2), ts_ClientSlot(3,4)));
	var HTTPResponse res;

	/* Create a new slotmap via HTTP */
	res := f_rsres_post_slotmap(sm);

	/* verify that the slotmap exists and is NEW */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, NEW);

	/* connect a bankd for that slotmap */
	f_rspro_connect_client(0);

	/* connect a client for that slotmap */
	f_rspro_connect_client(1);

	/* expect the slotmap to be pushed to bank and ACK it */
	as_rspro_create_mapping(0, sm.client, sm.bank);

	/* verify that the slotmap exists and is ACTIVE */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, ACTIVE);

	/* expect the client to be configured with bankd side settings */
	as_rspro_cfg_client_bank(1, sm.bank, ?/*FIXME*/);

	f_sleep(1.0);

	/* delete the slotmap via REST */
	res := f_rsres_delete_slotmap(sm.bank);

	/* verify the slotmap is gone from REST interface immediately */
	f_ensure_slotmaps({});

	/* verify the slotmap is removed from bankd */
	as_rspro_remove_mapping(0, sm.client, sm.bank);

	/* verify the slotmap is removed from client by setting IP/port to '0' */
	as_rspro_cfg_client_bank(1, ?, tr_IpPort(ts_IPv4("0.0.0.0"), 0));
}


/* Add a slotmap to a currently active bank */
testcase TC_slotmap_add_active_bank() runs on test_CT {
	var ComponentIdentity rspro_id := valueof(ts_CompId(remsimBankd, testcasename()));

	f_init();
	f_rspro_init(rspro[0], mp_server_ip, mp_server_port, rspro_id, 0);
	rspro[0].rspro_bank_id := 1;
	rspro[0].rspro_bank_nslots := 8;

	f_rsres_init();
	var JsSlotmap sm := valueof(ts_JsSlotmap(ts_BankSlot(1,2), ts_ClientSlot(3,4)));
	var HTTPResponse res;

	/* connect a bankd for that slotmap */
	f_rspro_connect_client(0);

	/* Create a new slotmap via HTTP */
	res := f_rsres_post_slotmap(sm);

	/* expect the slotmap to be pushed to bank and ACK it */
	as_rspro_create_mapping(0, sm.client, sm.bank);

	/* verify that the slotmap exists and is ACTIVE */
	f_ensure_slotmap_exists_only(sm.client, sm.bank, ACTIVE);
}




/* TODO
 * - connect client w/slotmap; delete slotmap via REST (see if it is deleted)
 *   - don't acknowledge delete from client, disconnect client (see if slotmap is deleted)

 * - connect from unknown client (name not known, no clientId provisioned?
 * - add client name/ID mappings from REST API?
 */


control {
	execute( TC_connect_and_nothing() );
	execute( TC_connect_client() );
	execute( TC_connect_client_duplicate() );
	execute( TC_connect_bank() );
	execute( TC_connect_bank_duplicate() );
	execute( TC_slotmap_add() );
	execute( TC_slotmap_add_conn_cl_b() );
	execute( TC_slotmap_add_out_of_range() );
	execute( TC_conn_cl_b_slotmap_add() );
	execute( TC_slotmap_del_new() );
	execute( TC_slotmap_del_nonexistant() );
	execute( TC_slotmap_del_unack() );
	execute( TC_slotmap_del_active() );
	execute( TC_slotmap_del_active_client() );
	execute( TC_slotmap_add_active_bank() );
}


}
