/* 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 TELNETasp_PortType all;
import from Osmocom_Types all;
import from TCCConversion_Functions all;
import from Socket_API_Definitions 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_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_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(AMI_FIELD_ACTION, val);
template (present) AMI_Field
tr_AMI_Field_ActionId(template (present) charstring val := ?) := tr_AMI_Field(AMI_FIELD_ACTION_ID, val);
template (present) AMI_Field
tr_AMI_Field_Username(template (present) charstring val := ?) := tr_AMI_Field(AMI_FIELD_USERNAME, val);
template (present) AMI_Field
tr_AMI_Field_Secret(template (present) charstring val := ?) := tr_AMI_Field(AMI_FIELD_SECRET, val);
template (present) AMI_Field
tr_AMI_Field_Response(template (present) charstring val := ?) := tr_AMI_Field(AMI_FIELD_RESPONSE, val);
/* Extensions: */
template (present) AMI_Field
tr_AMI_Field_Registration(template (present) charstring val := ?) := tr_AMI_Field(AMI_FIELD_REGISTRATION, val);


template (present) AMI_Field
tr_AMI_Field_ResponseSuccess := tr_AMI_Field(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) := {
	ts_AMI_Field_Action("Login"),
	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 := ?) := superset(
	tr_AMI_Field_Action("Login"),
	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)
);


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

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

type component AMI_Adapter_CT {
	port TELNETasp_PT AMI;
	port AMI_Msg_PT CLIENT;
}

function f_AMI_Adapter_main() runs on AMI_Adapter_CT {
	var AMI_Msg msg;

	var charstring rx, buf := "";
	var integer fd;

	map(self:AMI, system:AMI);

	while (true) {

		alt {
		[] AMI.receive(pattern "\n") {
			buf := buf & "\n";
			msg := dec_AMI_Msg(buf);
			buf := "";
			CLIENT.send(msg);
			};
		[] AMI.receive(charstring:?) -> value rx {
			buf := buf & rx;
			};
		[] AMI.receive(integer:?) -> value fd {
			if (fd == -1) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
							"AMI Telnet Connection Failure: " & int2str(fd));
			} else {
				/* telnet connection succeeded */
			}
			}
		[] 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);
			AMI.send(tx_txt);
			}
		}
	}
}


/*
 * 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;

}

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) {
	f_ami_transceive_match_response_success(pt, ts_AMI_Action_Login(username, secret));
}

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));
}

}
