/* OpenBSC Iu related interface to quagga VTY */
/* (C) 2016 by sysmocom s.m.f.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <stdlib.h>
#include <string.h>

#include <osmocom/core/logging.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/logging.h>
#include <osmocom/sigtran/osmo_ss7.h>
#include <osmocom/sigtran/sccp_sap.h>

#include <osmocom/ranap/iu_client.h>

static enum ranap_nsap_addr_enc *g_rab_assign_addr_enc = NULL;

DEFUN(cfg_iu_asn1_debug,
      cfg_iu_asn1_debug_cmd,
      "asn1 debug (1|0)",
      "ASN.1 settings\n"
      "Enable ASN.1 debug messages\n"
      "Log ASN.1 debug messages to stderr\n"
      "Do not log ASN.1 debug messages to stderr\n")
{
	asn_debug = atoi(argv[0]);
	return CMD_SUCCESS;
}

DEFUN(cfg_iu_asn1_xer_print,
      cfg_iu_asn1_xer_print_cmd,
      "asn1 xer-print (1|0)",
      "ASN.1 settings\n"
      "Log human readable representations of all ASN.1 messages to stderr\n"
      "Log XML representation of all ASN.1 messages to stderr\n"
      "Do not log decoded ASN.1 messages to stderr\n")
{
	asn1_xer_print = atoi(argv[0]);
	return CMD_SUCCESS;
}

#define IU_STR "Iu interface protocol options\n"
DEFUN(cfg_iu_rab_assign_addr_enc, cfg_iu_rab_assign_addr_enc_cmd,
      "iu rab-assign-addr-enc (x213|v4raw)",
      IU_STR
      "Choose RAB Assignment's Transport Layer Address encoding\n"
      "ITU-T X.213 compliant address encoding (default)\n"
      "32bit length raw IPv4 address (for ip.access nano3G)\n")
{
	if (!g_rab_assign_addr_enc) {
		vty_out(vty, "%%RAB Assignment Transport Layer Address"
			" encoding not available%s", VTY_NEWLINE);
		return CMD_WARNING;
	}

	if (strcmp(argv[0], "v4raw") == 0)
		*g_rab_assign_addr_enc = RANAP_NSAP_ADDR_ENC_V4RAW;
	else
		*g_rab_assign_addr_enc = RANAP_NSAP_ADDR_ENC_X213;
	return CMD_SUCCESS;
}

extern struct osmo_sccp_addr local_sccp_addr;

DEFUN(cfg_iu_local_addr_pc, cfg_iu_local_addr_pc_cmd,
	"iu local-address point-code PC",
	IU_STR "Local SCCP Address\n")
{
	local_sccp_addr.presence = OSMO_SCCP_ADDR_T_PC | OSMO_SCCP_ADDR_T_SSN;
	local_sccp_addr.ri = OSMO_SCCP_RI_SSN_PC;
	local_sccp_addr.pc = osmo_ss7_pointcode_parse(NULL, argv[0]);

	return CMD_SUCCESS;
}

/* TODO: GT address configuration, in line with 4.5.1.1.1 of TS 25.410 */

int ranap_iu_vty_config_write(struct vty *vty, const char *indent)
{
	if (!g_rab_assign_addr_enc) {
		vty_out(vty, "%%RAB Assignment Transport Layer Address"
			" encoding not available%s", VTY_NEWLINE);
		return CMD_WARNING;
	}

	switch (*g_rab_assign_addr_enc) {
	case RANAP_NSAP_ADDR_ENC_V4RAW:
		vty_out(vty, "%siu rab-assign-addr-enc v4raw%s", indent,
			VTY_NEWLINE);
		break;
	case RANAP_NSAP_ADDR_ENC_X213:
		/* default value, no need to write anything */
		break;
	default:
		LOGP(0, LOGL_ERROR, "Invalid value for"
		     " iu.rab_assign_addr_enc: %d\n",
		     *g_rab_assign_addr_enc);
		return CMD_WARNING;
	}

	vty_out(vty, "%siu local-address point-code %s%s", indent,
		osmo_ss7_pointcode_print(NULL, local_sccp_addr.pc), VTY_NEWLINE);

	if (asn_debug)
		vty_out(vty, "%sasn1 debug 1%s", indent, VTY_NEWLINE);

	if (asn1_xer_print)
		vty_out(vty, "%sasn1 xer-print 1%s", indent, VTY_NEWLINE);

	return CMD_SUCCESS;
}

void ranap_iu_vty_init(int iu_parent_node, enum ranap_nsap_addr_enc *rab_assign_addr_enc)
{
	g_rab_assign_addr_enc = rab_assign_addr_enc;

	install_element(iu_parent_node, &cfg_iu_rab_assign_addr_enc_cmd);
	install_element(iu_parent_node, &cfg_iu_local_addr_pc_cmd);

	/* Technically, these are global ASN.1 settings and not necessarily limited to the Iu interface.
	 * Practically, only Iu users will use ASN.1 in Osmocom programs -- at least so far. So it is
	 * easiest to have these commands under 'iu'. */
	install_element(iu_parent_node, &cfg_iu_asn1_debug_cmd);
	install_element(iu_parent_node, &cfg_iu_asn1_xer_print_cmd);
}
