/* Asterisk's AMI interface functions in TTCN-3
 * (C) 2024 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * Author: Pau Espin Pedrol <pespin@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
 */

/*
 * https://docs.asterisk.org/Configuration/Interfaces/Asterisk-Manager-Interface-AMI/AMI-v2-Specification/
 */
module AMI_Functions {

import from Misc_Helpers all;
import from Osmocom_Types all;
import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from Socket_API_Definitions all;
import from TCCConversion_Functions all;

modulepar {
	float mp_ami_prompt_timeout := 10.0;
}

const charstring AMI_FIELD_ACTION := "Action";
const charstring AMI_FIELD_ACTION_ID := "ActionID";
const charstring AMI_FIELD_EVENT := "Event";
const charstring AMI_FIELD_USERNAME := "Username";
const charstring AMI_FIELD_SECRET := "Secret";
const charstring AMI_FIELD_RESPONSE := "Response";

/* Extensions: */
const charstring AMI_FIELD_REGISTRATION := "Registration";

type record AMI_Field {
	charstring	key,
	charstring	val
} with {
	encode "TEXT"
	variant "SEPARATOR(': ', ':\s+')"
};

type set of AMI_Field AMI_Msg with {
	encode "TEXT"
	variant "SEPARATOR('\r\n', '(\r\n)|[\n]')"
	variant "END('\r\n', '(\r\n)|[\n]')"
};

external function enc_AMI_Msg(in AMI_Msg msg) return charstring
	with { extension "prototype(convert) encode(TEXT)" }
external function dec_AMI_Msg(in charstring stream) return AMI_Msg
	with { extension "prototype(convert) decode(TEXT)" }

template (value) AMI_Field
ts_AMI_Field(template (value) charstring key,
	     template (value) charstring val) := {
	key := key,
	val := val
};

template (present) AMI_Field
tr_AMI_Field(template (present) charstring key := ?,
	     template (present) charstring val := ?) := {
	key := key,
	val := val
};

/*
 * Field Templates:
 */

template (value) AMI_Field
ts_AMI_Field_Action(template (value) charstring val) := ts_AMI_Field(AMI_FIELD_ACTION, val);
template (value) AMI_Field
ts_AMI_Field_ActionId(template (value) charstring val) := ts_AMI_Field(AMI_FIELD_ACTION_ID, val);
template (value) AMI_Field
ts_AMI_Field_Event(template (value) charstring val) := ts_AMI_Field(AMI_FIELD_EVENT, val);
template (value) AMI_Field
ts_AMI_Field_Username(template (value) charstring val) := ts_AMI_Field(AMI_FIELD_USERNAME, val);
template (value) AMI_Field
ts_AMI_Field_Secret(template (value) charstring val) := ts_AMI_Field(AMI_FIELD_SECRET, val);
/* Extensions: */
template (value) AMI_Field
ts_AMI_Field_Registration(template (value) charstring val) := ts_AMI_Field(AMI_FIELD_REGISTRATION, val);

template (present) AMI_Field
tr_AMI_Field_Action(template (present) charstring val := ?) := tr_AMI_Field(pattern @nocase AMI_FIELD_ACTION, val);
template (present) AMI_Field
tr_AMI_Field_ActionId(template (present) charstring val := ?) := tr_AMI_Field(pattern @nocase AMI_FIELD_ACTION_ID, val);
template (present) AMI_Field
tr_AMI_Field_Event(template (present) charstring val := ?) := tr_AMI_Field(pattern @nocase AMI_FIELD_EVENT, val);
template (present) AMI_Field
tr_AMI_Field_Username(template (present) charstring val := ?) := tr_AMI_Field(pattern @nocase AMI_FIELD_USERNAME, val);
template (present) AMI_Field
tr_AMI_Field_Secret(template (present) charstring val := ?) := tr_AMI_Field(pattern @nocase AMI_FIELD_SECRET, val);
template (present) AMI_Field
tr_AMI_Field_Response(template (present) charstring val := ?) := tr_AMI_Field(pattern @nocase AMI_FIELD_RESPONSE, val);
/* Extensions: */
template (present) AMI_Field
tr_AMI_Field_Registration(template (present) charstring val := ?) := tr_AMI_Field(pattern @nocase AMI_FIELD_REGISTRATION, val);


template (present) AMI_Field
tr_AMI_Field_ResponseSuccess := tr_AMI_Field(pattern @nocase AMI_FIELD_RESPONSE, "Success");


/***********************
 * Message Templates:
 ***********************/

/*
 * ACTIONS
 */

/* Action: Login
 * Username: <value>
 * Secret: <value>
 */
template (value) AMI_Msg
ts_AMI_Action_Login(charstring username,
		    charstring secret,
		    template (value) charstring action_id := "0001") := {
	ts_AMI_Field_Action("Login"),
	ts_AMI_Field_ActionId(action_id),
	ts_AMI_Field_Username(username),
	ts_AMI_Field_Secret(secret)
};

template (present) AMI_Msg
tr_AMI_Action_Login(template(present) charstring username := ?,
		    template(present) charstring secret := ?,
		    template (present) charstring action_id := ?) := superset(
	tr_AMI_Field_Action("Login"),
	tr_AMI_Field_ActionId(action_id),
	tr_AMI_Field_Username(username),
	tr_AMI_Field_Secret(secret)
);

/* Action: PJSIPRegister
 * ActionID: <value>
 * Registration: volte_ims
 */
template (value) AMI_Msg
ts_AMI_Action_PJSIPRegister(template (value) charstring registration := "volte_ims",
			    template (value) charstring action_id := "0001") := {
	ts_AMI_Field_Action("PJSIPRegister"),
	ts_AMI_Field_ActionId(action_id),
	ts_AMI_Field_Registration(registration)
};
template (present) AMI_Msg
tr_AMI_Action_PJSIPRegister(template (present) charstring registration := ?,
			    template (present) charstring action_id := ?) := {
	tr_AMI_Field_Action("PJSIPRegister"),
	tr_AMI_Field_ActionId(action_id),
	tr_AMI_Field_Registration(registration)
};

/*
 * RESPONSES
 */

/* Response: Success
 */
template (present) AMI_Msg
tr_AMI_Response_Success := superset(
	tr_AMI_Field_ResponseSuccess
);

/* Response: Success
 * ActionId: <value>
 */
template (present) AMI_Msg
tr_AMI_Response_Success_ActionId(template (present) charstring action_id := ?) := superset(
	tr_AMI_Field_ResponseSuccess,
	tr_AMI_Field_ActionId(action_id)
);

/*
 * EVENTS
 */
template (present) AMI_Msg
tr_AMI_Event(template (present) charstring ev_name := ?) := superset(
	tr_AMI_Field_Event(ev_name)
);

/* Event: FullyBooted
 * Privilege: system,all
 * Status: Fully Booted
 * Uptime: 4
 * LastReload: 4 *
 */
template (present) AMI_Msg
tr_AMI_Event_FullyBooted := tr_AMI_Event("FullyBooted");

/***********************
 * Adapter:
 ***********************/

type record AMI_Adapter_Parameters {
	charstring			remote_host,
	IPL4asp_Types.PortNumber	remote_port,
	charstring			local_host,
	IPL4asp_Types.PortNumber	local_port,
	charstring			welcome_str
}

const AMI_Adapter_Parameters c_default_AMI_Adapter_pars := {
	remote_host := "127.0.0.1",
	remote_port := 5038,
	local_host := "0.0.0.0",
	local_port := 0,
	welcome_str := "Asterisk Call Manager/9.0.0\r\n"
};

type port AMI_Msg_PT message {
	inout AMI_Msg;
} with { extension "internal" };

type component AMI_Adapter_CT {
	port IPL4asp_PT IPL4;
	port AMI_Msg_PT CLIENT;
	var AMI_Adapter_Parameters g_pars;

	/* Connection identifier of the client itself */
	var IPL4asp_Types.ConnectionId g_self_conn_id := -1;
}

/* Function to use to connect as client to a remote IPA Server */
private function f_AMI_Adapter_connect() runs on AMI_Adapter_CT {
	var IPL4asp_Types.Result res;
	map(self:IPL4, system:IPL4);
	res := IPL4asp_PortType.f_IPL4_connect(IPL4, g_pars.remote_host, g_pars.remote_port,
					       g_pars.local_host, g_pars.local_port, 0, { tcp:={} });
	if (not ispresent(res.connId)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("Could not connect AMI socket from ", g_pars.local_host, " port ",
				g_pars.local_port, " to ", g_pars.remote_host, " port ", g_pars.remote_port,
				"; check your configuration"));
	}
	g_self_conn_id := res.connId;
	log("AMI connected, ConnId=", g_self_conn_id)
}

private function f_ASP_RecvFrom_msg_to_charstring(ASP_RecvFrom rx_rf) return charstring {
	return oct2char(rx_rf.msg);
}

/* Function to use to connect as client to a remote IPA Server */
private function f_AMI_Adapter_wait_rx_welcome_str() runs on AMI_Adapter_CT {
	var ASP_RecvFrom rx_rf;
	var charstring rx_str;
	timer Twelcome := 3.0;

	Twelcome.start;
	alt {
	[] IPL4.receive(ASP_RecvFrom:?) -> value rx_rf {
		rx_str := f_ASP_RecvFrom_msg_to_charstring(rx_rf);
		if (g_pars.welcome_str != rx_str) {
					Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("AMI Welcome message mismatch: '", rx_str,
						"' vs exp '", g_pars.welcome_str, "'"));
		}
	}
	[] Twelcome.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("AMI Welcome timeout"));
	}
	}
	Twelcome.stop;
	log("AMI Welcome message received: '", rx_str, "'");
}

private function dec_AMI_Msg_ext(charstring txt) return AMI_Msg {
	log("AMI dec: '", txt, "'");
	/* TEXT Enc/dec is not happy with empty values, workaround it: */
	var charstring patched_txt := f_str_replace(txt, "Challenge: \r\n", "");
	patched_txt := f_str_replace(patched_txt, "AccountCode: \r\n", "");
	patched_txt := f_str_replace(patched_txt, "Value: \r\n", "");
	patched_txt := f_str_replace(patched_txt, "DestExten: \r\n", "");
	patched_txt := f_str_replace(patched_txt, "Exten: \r\n", "");
	patched_txt := f_str_replace(patched_txt, "Extension: \r\n", "");
	patched_txt := f_str_replace(patched_txt, "Hint: \r\n", "");

	/* "AppData" field sometimes has a value containing separator ": ", which makes
	 * TEXT dec not happy. Workaround it for now by removing the whole field line:
	 * "AppData: 5,0502: Call pjsip endpoint from 0501\r\n"
	 */
	var integer pos := f_strstr(patched_txt, "AppData: ", 0);
	if (pos >= 0) {
		var integer pos_end := f_strstr(patched_txt, "\r\n", pos) + lengthof("\r\n");
		var charstring to_remove := substr(patched_txt, pos, pos_end - pos);
		patched_txt := f_str_replace(patched_txt, to_remove, "");
	}

	log("AMI patched dec: '", patched_txt, "'");
	return dec_AMI_Msg(patched_txt);
}

function f_AMI_Adapter_main(AMI_Adapter_Parameters pars := c_default_AMI_Adapter_pars)
		runs on AMI_Adapter_CT {
	var AMI_Msg msg;
	var charstring rx, buf := "";
	var integer fd;
	var ASP_RecvFrom rx_rf;
	var ASP_Event rx_ev;

	g_pars := pars;

	f_AMI_Adapter_connect();

	f_AMI_Adapter_wait_rx_welcome_str();

	while (true) {

		alt {
		[] IPL4.receive(ASP_RecvFrom:?) -> value rx_rf {
			var charstring rx_str := f_ASP_RecvFrom_msg_to_charstring(rx_rf);
			log("AMI rx: '", rx_str, "'");
			buf := buf & rx_str;
			log("AMI buf: '", buf, "'");

			/* If several messages come together */
			var boolean last_is_complete := f_str_endswith(buf, "\r\n\r\n");
			var Misc_Helpers.ro_charstring msgs := f_str_split(buf, "\r\n\r\n");
			log("AMI split: ", msgs);
			if (lengthof(msgs) > 0) {
				for (var integer i := 0; i < lengthof(msgs) - 1; i := i + 1) {
					var charstring txt := msgs[i] & "\r\n";
					msg := dec_AMI_Msg_ext(txt);
					CLIENT.send(msg);
				}
				if (last_is_complete) {
					var charstring txt := msgs[lengthof(msgs) - 1] & "\r\n";
					msg := dec_AMI_Msg_ext(txt);
					CLIENT.send(msg);
					buf := "";
				} else {
					buf := msgs[lengthof(msgs) - 1];
				}
			}
			log("AMI remain buf: '", buf, "'");
			}
		[] IPL4.receive(ASP_ConnId_ReadyToRelease:?) {
			}

		[] IPL4.receive(ASP_Event:?) -> value rx_ev {
			log("Rx AMI ASP_Event: ", rx_ev);
			}
		[] CLIENT.receive(AMI_Msg:?) -> value msg {
			/* TODO: in the future, queue Action if there's already one Action in transit, to fullfill AMI requirements. */
			var charstring tx_txt := enc_AMI_Msg(msg) & "\r\n";

			var ASP_SendTo tx := {
				connId := g_self_conn_id,
				remName := g_pars.remote_host,
				remPort := g_pars.remote_port,
				proto := { tcp := {} },
				msg := char2oct(tx_txt)
			};
			IPL4.send(tx);
			}
		}
	}
}


/*
 * Functions:
 */

/* Generate a random "ActionId" value: */
function f_gen_action_id() return charstring {
	return hex2str(f_rnd_hexstring(16));
}

function f_ami_msg_find(AMI_Msg msg,
			template (present) charstring key := ?)
return template (omit) AMI_Field {
	var integer i;

	for (i := 0; i < lengthof(msg); i := i + 1) {
		if (not ispresent(msg[i])) {
			continue;
		}
		if (match(msg[i].key, key)) {
			return msg[i];
		}
	}
	return omit;
}

function f_ami_msg_find_or_fail(AMI_Msg msg,
				template (present) charstring key := ?)
return AMI_Field {
	var template (omit) AMI_Field field;
	field := f_ami_msg_find(msg, key);
	if (istemplatekind(field, "omit")) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("Key ", key, " not found in ", msg));
	}
	return valueof(field);
}

function f_ami_msg_get_value(AMI_Msg msg,
			     template (present) charstring key := ?)
return template (omit) charstring {
	var template (omit) AMI_Field field;
	field := f_ami_msg_find(msg, key);
	if (istemplatekind(field, "omit")) {
		return omit;
	}
	return field.val;
}

function f_ami_msg_get_value_or_fail(AMI_Msg msg,
				     template (present) charstring key := ?)
return template charstring {
	var AMI_Field field;
	field := f_ami_msg_find_or_fail(msg, key);
	return field.val;
}

function f_ami_transceive_ret(AMI_Msg_PT pt, template (value) AMI_Msg tx_msg, float rx_timeout := 10.0) return AMI_Msg {
	var AMI_Msg rx_msg;
	timer T;

	T.start(rx_timeout);
	pt.send(tx_msg);
	alt {
	[] pt.receive(AMI_Msg:?) -> value rx_msg;
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("AMI Response timeout: ", tx_msg));
		}
	}
	T.stop;
	return rx_msg;

}

altstep as_ami_rx_ignore(AMI_Msg_PT pt)
{
	var AMI_Msg msg;
	[] pt.receive(AMI_Msg:?) -> value msg {
		log("Ignoring AMI message := ", msg);
		repeat;
	}
}

private altstep as_ami_rx_fail(AMI_Msg_PT pt, template AMI_Msg exp_msg := *)
{
	var AMI_Msg msg;
	[] pt.receive(AMI_Msg:?) -> value msg {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Received unexpected AMI message := ", msg, "\nvs exp := ", exp_msg));
	}
}

altstep as_ami_expect_msg(AMI_Msg_PT pt, template (present) AMI_Msg msg_expect, boolean fail_others := true)
{
	[] pt.receive(msg_expect);
	[fail_others] as_ami_rx_fail(pt, msg_expect);
}

function f_ami_transceive_match(AMI_Msg_PT pt,
				template (value) AMI_Msg tx_msg,
				template (present) AMI_Msg exp_ret := ?,
				boolean fail_others := true,
				float rx_timeout := 10.0) return AMI_Msg {
	var AMI_Msg rx_msg;
	timer T;

	T.start(rx_timeout);
	pt.send(tx_msg);
	alt {
	[] pt.receive(exp_ret) -> value rx_msg;
	[not fail_others] pt.receive(AMI_Msg:?) -> value rx_msg {
		log("AMI: Ignoring Rx msg ", rx_msg);
		repeat;
	}
	[fail_others] as_ami_rx_fail(pt, exp_ret);
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("AMI Response timeout: ", tx_msg));
		}
	}
	T.stop;
	return rx_msg;
}

function f_ami_transceive_match_response_success(AMI_Msg_PT pt,
						 template (value) AMI_Msg tx_msg) {
	var template (present) AMI_Msg exp_resp;
	var template (omit) charstring action_id := f_ami_msg_get_value(valueof(tx_msg), AMI_FIELD_ACTION_ID);
	if (isvalue(action_id)) {
		exp_resp := tr_AMI_Response_Success_ActionId(action_id);
	} else {
		exp_resp := tr_AMI_Response_Success;
	}
	f_ami_transceive_match(pt, tx_msg, exp_resp);
}

function f_ami_action_login(AMI_Msg_PT pt, charstring username, charstring secret) {
	var charstring reg_action_id := f_gen_action_id();
	f_ami_transceive_match_response_success(pt, ts_AMI_Action_Login(username, secret, reg_action_id));
}

function f_ami_action_PJSIPRegister(AMI_Msg_PT pt, charstring register) {
	var charstring reg_action_id := f_gen_action_id();
	f_ami_transceive_match_response_success(pt, ts_AMI_Action_PJSIPRegister(register, reg_action_id));
}

private function f_ami_selftest_decode(charstring txt) {
	log("Text to decode: '", txt, "'");
	var AMI_Msg msg := dec_AMI_Msg(txt);
	log("AMI_Msg decoded: ", msg);
}

function f_ami_selftest() {
	f_ami_selftest_decode("AppData: 5,0502: Call pjsip endpoint from 0501\r\n");
}

}
