/* Osmocom VTY interface functions in TTCN-3
 * (C) 2017-2018 Harald Welte <laforge@gnumonks.org>
 * contributions by sysmocom - s.f.m.c. GmbH
 * 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
 */

module Osmocom_VTY_Functions {
	import from TELNETasp_PortType all;
	import from Osmocom_Types all;

	modulepar {
		charstring mp_prompt_prefix := "OpenBSC";
		float mp_prompt_timeout := 2.0;
	}

	const charstring VTY_VIEW_SUFFIX := "> ";
	const charstring VTY_ENABLE_SUFFIX := "# ";
	const charstring VTY_CFG_SUFFIX := "(*)";

	template charstring t_vty_unknown := pattern "*% Unknown command.";

	/* configure prompts in TELNETasp module */
	function f_vty_set_prompts(TELNETasp_PT pt, charstring prompt_prefix := mp_prompt_prefix) {
		var ASP_TelnetDynamicConfig vty_prompt[3] := {
			{
				prompt := {
					id := 1,
					prompt := prompt_prefix & VTY_VIEW_SUFFIX,
					has_wildcards := false
				}
			}, {
				prompt := {
					id := 2,
					prompt := prompt_prefix & VTY_ENABLE_SUFFIX,
					has_wildcards := false
				}
			}, {
				prompt := {
					id := 3,
					prompt := prompt_prefix & VTY_CFG_SUFFIX,
					has_wildcards := true
				}
			}
		};

		/* set some configuration that isn't possible to express
		 * in the config file due to syntactic restrictions (Who invents config
		 * files that don't permit regular expressions? */
		for (var integer i := 0; i < sizeof(vty_prompt); i:= i + 1) {
			pt.send(vty_prompt[i]);
		}
	}

	/* wait for any of the permitted prompts; buffer + return all intermediate output */
	function f_vty_wait_for_prompt(TELNETasp_PT pt, boolean strict := true, charstring log_label := "(?)")
	return charstring {
		var charstring rx, buf := "";
		var integer fd;
		timer T;

		T.start(mp_prompt_timeout);
		alt {
		[] pt.receive(pattern "[\w-]+" & VTY_VIEW_SUFFIX) { };
		[] pt.receive(pattern "[\w-]+\# ") { };
		[] pt.receive(pattern "[\w-]+\(*\)\# ") { };
		[] pt.receive(t_vty_unknown) -> value rx {
			if (strict) {
				setverdict(fail, "VTY: Unknown Command: " & log_label);
				mtc.stop;
			} else {
				log("VTY: Unknown Command (ignored): " & log_label);
				buf := buf & rx;
				repeat;
			}
			};
		[] pt.receive(charstring:?) -> value rx { buf := buf & rx; repeat };
		[] pt.receive(integer:?) -> value fd {
			if (fd == -1) {
				setverdict(fail, "VTY Telnet Connection Failure: " & log_label);
				mtc.stop;
			} else {
				repeat; /* telnet connection succeeded */
			}
		}
		[] T.timeout {
			setverdict(fail, "VTY Timeout for prompt: " & log_label);
			mtc.stop;
			};
		}
		T.stop;
		return buf;
	}

	/* send a VTY command and obtain response until prompt is received */
	function f_vty_transceive_ret(TELNETasp_PT pt, charstring tx, boolean strict := true) return charstring {
		pt.send(tx);
		return f_vty_wait_for_prompt(pt, strict, tx);
	}

	/* send a VTY command and obtain response until prompt is received */
	function f_vty_transceive(TELNETasp_PT pt, charstring tx, boolean strict := true) {
		var charstring unused := f_vty_transceive_ret(pt, tx, strict);
	}

	type integer BtsNr (0..255);
	type integer BtsTrxNr (0..255);
	type integer BtsTimeslotNr (0..7);
	type integer MscNr (0..255);
	type integer Cs7Nr (0..255);

	type charstring BtsGprsMode ("none", "gprs", "egrps");

	/* enter the'confiugration' mode of the VTY */
	function f_vty_enter_config(TELNETasp_PT pt) {
		f_vty_transceive(pt, "configure terminal")
	}

	function f_vty_enter_cfg_network(TELNETasp_PT pt) {
		f_vty_enter_config(pt);
		f_vty_transceive(pt, "network")
	}

	function f_vty_enter_cfg_bts(TELNETasp_PT pt, BtsNr bts := 0) {
		f_vty_enter_cfg_network(pt);
		f_vty_transceive(pt, "bts " & int2str(bts));
	}

	function f_vty_enter_cfg_trx(TELNETasp_PT pt, BtsNr bts := 0, BtsTrxNr trx := 0) {
		f_vty_enter_cfg_bts(pt, bts);
		f_vty_transceive(pt, "trx " & int2str(trx));
	}

	function f_vty_enter_cfg_ts(TELNETasp_PT pt, BtsNr bts := 0, BtsTrxNr trx := 0, BtsTimeslotNr ts) {
		f_vty_enter_cfg_trx(pt, bts, trx);
		f_vty_transceive(pt, "timeslot " & int2str(ts));
	}

	function f_vty_enter_cfg_msc(TELNETasp_PT pt, MscNr msc := 0) {
		f_vty_enter_config(pt);
		f_vty_transceive(pt, "msc " & int2str(msc));
	}

	function f_vty_enter_cfg_cs7_inst(TELNETasp_PT pt, Cs7Nr cs7_inst := 0) {
		f_vty_enter_config(pt);
		f_vty_transceive(pt, "cs7 instance " & int2str(cs7_inst));
	}

type record of charstring rof_charstring;
function f_vty_config3(TELNETasp_PT pt, rof_charstring config_nodes, rof_charstring cmds)
{
	/* enter config mode; enter node */
	f_vty_enter_config(pt);
	for (var integer i := 0; i < sizeof(config_nodes); i := i+1) {
		f_vty_transceive(pt, config_nodes[i]);
	}
	/* execute commands */
	for (var integer i := 0; i < sizeof(cmds); i := i+1) {
		f_vty_transceive(pt, cmds[i]);
	}
	/* leave config mode */
	f_vty_transceive(pt, "end");
}

function f_vty_config2(TELNETasp_PT pt, rof_charstring config_nodes, charstring cmd)
{
	f_vty_config3(pt, config_nodes, { cmd });
}

function f_vty_config(TELNETasp_PT pt, charstring config_node, charstring cmd)
{
	f_vty_config2(pt, {config_node}, cmd);
}

function f_vty_cfg_bts(TELNETasp_PT pt, BtsNr bts := 0, rof_charstring cmds) {
	f_vty_config3(pt, {"network", "bts " & int2str(bts)}, cmds);
}

function f_vty_cfg_msc(TELNETasp_PT pt, MscNr msc := 0, rof_charstring cmds) {
	f_vty_config3(pt, {"msc " & int2str(msc)}, cmds);
}

function f_vty_transceive_match(TELNETasp_PT pt, charstring cmd, template charstring exp_ret) {
	var charstring ret := f_vty_transceive_ret(pt, cmd);
	if (not match(ret, exp_ret)) {
		setverdict(fail, "Non-matching VTY response: ", ret);
		mtc.stop;
	}
}

function f_vty_transceive_not_match(TELNETasp_PT pt, charstring cmd, template charstring exp_ret) {
	var charstring ret := f_vty_transceive_ret(pt, cmd);
	if (match(ret, exp_ret)) {
		setverdict(fail, "Unexpected matching VTY response: ", ret);
		mtc.stop;
	}
}

function f_vty_transceive_match_regex(TELNETasp_PT pt, charstring cmd, charstring regex, integer groupno) return charstring
{
	var charstring resp := f_vty_transceive_ret(pt, cmd);
	return regexp(resp, regex, groupno);
}

function f_vty_transceive_match_regexp_retry(TELNETasp_PT pt, charstring cmd, charstring regex,
					     integer groupno, integer num_attempts, float retry_delay) return charstring
{
	 while (num_attempts > 0) {
		var charstring ret := f_vty_transceive_match_regex(pt, cmd, regex, groupno);
		if (ret != "") {
			return ret;
		}
		f_sleep(retry_delay);
		num_attempts := num_attempts - 1;
	}

	setverdict(fail, "No matching VTY response for regular expression '", regex,
		   "' after ", num_attempts, " attempts." );
	mtc.stop;
}

}
