/* Copyright 2019 by sysmocom s.f.m.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 <osmocom/vty/vty.h>
#include <osmocom/vty/command.h>
#include <osmocom/mslookup/mslookup_client_mdns.h>
#include <osmocom/mslookup/mdns.h>
#include <osmocom/hlr/hlr_vty.h>
#include <osmocom/hlr/mslookup_server.h>
#include <osmocom/hlr/mslookup_server_mdns.h>
#include <osmocom/gsupclient/gsup_peer_id.h>

struct cmd_node mslookup_node = {
	MSLOOKUP_NODE,
	"%s(config-mslookup)# ",
	1,
};

DEFUN(cfg_mslookup,
      cfg_mslookup_cmd,
      "mslookup",
      "Configure Distributed GSM mslookup")
{
	vty->node = MSLOOKUP_NODE;
	return CMD_SUCCESS;
}

static int mslookup_server_mdns_bind(struct vty *vty, int argc, const char **argv)
{
	const char *ip_str = argc > 0? argv[0] : g_hlr->mslookup.server.mdns.bind_addr.ip;
	const char *port_str = argc > 1? argv[1] : NULL;
	uint16_t port_nr = port_str ? atoi(port_str) : g_hlr->mslookup.server.mdns.bind_addr.port;
	struct osmo_sockaddr_str addr;
	if (osmo_sockaddr_str_from_str(&addr, ip_str, port_nr)
	    || !osmo_sockaddr_str_is_nonzero(&addr)) {
		vty_out(vty, "%% mslookup server: Invalid mDNS bind address: %s %u%s",
			ip_str, port_nr, VTY_NEWLINE);
		return CMD_WARNING;
	}

	g_hlr->mslookup.server.mdns.bind_addr = addr;
	g_hlr->mslookup.server.mdns.enable = true;
	g_hlr->mslookup.server.enable = true;
	mslookup_server_mdns_config_apply();
	return CMD_SUCCESS;
}

#define MDNS_STR "Multicast DNS related configuration\n"
#define MDNS_IP46_STR "multicast IPv4 address like " OSMO_MSLOOKUP_MDNS_IP4 \
			" or IPv6 address like " OSMO_MSLOOKUP_MDNS_IP6 "\n"
#define MDNS_PORT_STR "mDNS UDP Port number\n"
#define MDNS_DOMAIN_SUFFIX_STR "mDNS domain suffix (default: " OSMO_MDNS_DOMAIN_SUFFIX_DEFAULT "). This is appended" \
				 " and stripped from mDNS packets during encoding/decoding, so we don't collide with" \
				 " top-level domains administrated by IANA\n"
#define IP46_STR "IPv4 address like 1.2.3.4 or IPv6 address like a:b:c:d::1\n"
#define PORT_STR "Service-specific port number\n"

struct cmd_node mslookup_server_node = {
	MSLOOKUP_SERVER_NODE,
	"%s(config-mslookup-server)# ",
	1,
};

DEFUN(cfg_mslookup_server,
      cfg_mslookup_server_cmd,
      "server",
      "Enable and configure Distributed GSM mslookup server")
{
	vty->node = MSLOOKUP_SERVER_NODE;
	g_hlr->mslookup.server.enable = true;
	mslookup_server_mdns_config_apply();
	return CMD_SUCCESS;
}

DEFUN(cfg_mslookup_no_server,
      cfg_mslookup_no_server_cmd,
      "no server",
      NO_STR "Disable Distributed GSM mslookup server")
{
	g_hlr->mslookup.server.enable = false;
	mslookup_server_mdns_config_apply();
	return CMD_SUCCESS;
}

DEFUN(cfg_mslookup_server_mdns_bind,
      cfg_mslookup_server_mdns_bind_cmd,
      "mdns bind [IP] [<1-65535>]",
      MDNS_STR
      "Configure where the mDNS server listens for mslookup requests\n"
      MDNS_IP46_STR MDNS_PORT_STR)
{
	return mslookup_server_mdns_bind(vty, argc, argv);
}

DEFUN(cfg_mslookup_server_mdns_domain_suffix,
      cfg_mslookup_server_mdns_domain_suffix_cmd,
      "mdns domain-suffix DOMAIN_SUFFIX",
      MDNS_STR
      MDNS_DOMAIN_SUFFIX_STR
      MDNS_DOMAIN_SUFFIX_STR)
{
	osmo_talloc_replace_string(g_hlr, &g_hlr->mslookup.server.mdns.domain_suffix, argv[0]);
	mslookup_server_mdns_config_apply();
	return CMD_SUCCESS;
}

DEFUN(cfg_mslookup_server_no_mdns_bind,
      cfg_mslookup_server_no_mdns_bind_cmd,
      "no mdns bind",
      NO_STR "Disable server for mDNS mslookup (do not answer remote requests)\n")
{
	g_hlr->mslookup.server.mdns.enable = false;
	mslookup_server_mdns_config_apply();
	return CMD_SUCCESS;
}

struct cmd_node mslookup_server_msc_node = {
	MSLOOKUP_SERVER_MSC_NODE,
	"%s(config-mslookup-server-msc)# ",
	1,
};

DEFUN(cfg_mslookup_server_msc,
      cfg_mslookup_server_msc_cmd,
      "msc ipa-name .IPA_NAME",
      "Configure services for individual local MSCs\n"
      "Identify locally connected MSC by IPA Unit Name\n"
      "IPA Unit Name of the local MSC to configure\n")
{
	struct osmo_ipa_name msc_name;
	struct mslookup_server_msc_cfg *msc;
	osmo_ipa_name_set_str(&msc_name, argv_concat(argv, argc, 0));

	msc = mslookup_server_msc_get(&msc_name, true);
	if (!msc) {
		vty_out(vty, "%% Error creating MSC %s%s", osmo_ipa_name_to_str(&msc_name), VTY_NEWLINE);
		return CMD_WARNING;
	}
	vty->node = MSLOOKUP_SERVER_MSC_NODE;
	vty->index = msc;
	return CMD_SUCCESS;
}

#define SERVICE_NAME_STR \
	"mslookup service name, e.g. sip.voice or smpp.sms\n"

static struct mslookup_server_msc_cfg *msc_from_node(struct vty *vty)
{
	switch (vty->node) {
	case MSLOOKUP_SERVER_NODE:
		/* On the mslookup.server node, set services on the wildcard msc, without a particular name. */
		return mslookup_server_msc_get(&mslookup_server_msc_wildcard, true);
	case MSLOOKUP_SERVER_MSC_NODE:
		return vty->index;
	default:
		return NULL;
	}
}

DEFUN(cfg_mslookup_server_msc_service,
      cfg_mslookup_server_msc_service_cmd,
      "service NAME at IP <1-65535>",
      "Configure addresses of local services, as sent in replies to remote mslookup requests.\n"
      SERVICE_NAME_STR "at\n" IP46_STR PORT_STR)
{
	/* If this command is run on the 'server' node, it produces an empty unit name and serves as wildcard for all
	 * MSCs. If on a 'server' / 'msc' node, set services only for that MSC Unit Name. */
	struct mslookup_server_msc_cfg *msc = msc_from_node(vty);
	const char *service = argv[0];
	const char *ip_str = argv[1];
	const char *port_str = argv[2];
	struct osmo_sockaddr_str addr;

	if (!msc) {
		vty_out(vty, "%% Error: no MSC object on this node%s", VTY_NEWLINE);
		return CMD_WARNING;
	}

	if (osmo_sockaddr_str_from_str(&addr, ip_str, atoi(port_str))
	    || !osmo_sockaddr_str_is_nonzero(&addr)) {
		vty_out(vty, "%% mslookup server: Invalid address for service %s: %s %s%s",
			service, ip_str, port_str, VTY_NEWLINE);
		return CMD_WARNING;
	}

	if (mslookup_server_msc_service_set(msc, service, &addr)) {
		vty_out(vty, "%% mslookup server: Error setting service %s to %s %s%s",
			service, ip_str, port_str, VTY_NEWLINE);
		return CMD_WARNING;
	}
	return CMD_SUCCESS;
}

#define NO_SERVICE_AND_NAME_STR NO_STR "Remove one or more service address entries\n" SERVICE_NAME_STR

DEFUN(cfg_mslookup_server_msc_no_service,
      cfg_mslookup_server_msc_no_service_cmd,
      "no service NAME",
      NO_SERVICE_AND_NAME_STR)
{
	/* If this command is run on the 'server' node, it produces an empty unit name and serves as wildcard for all
	 * MSCs. If on a 'server' / 'msc' node, set services only for that MSC Unit Name. */
	struct mslookup_server_msc_cfg *msc = msc_from_node(vty);
	const char *service = argv[0];

	if (!msc) {
		vty_out(vty, "%% Error: no MSC object on this node%s", VTY_NEWLINE);
		return CMD_WARNING;
	}

	if (mslookup_server_msc_service_del(msc, service, NULL) < 1) {
		vty_out(vty, "%% mslookup server: cannot remove service '%s'%s",
			service, VTY_NEWLINE);
		return CMD_WARNING;
	}
	return CMD_SUCCESS;
}

DEFUN(cfg_mslookup_server_msc_no_service_addr,
      cfg_mslookup_server_msc_no_service_addr_cmd,
      "no service NAME at IP <1-65535>",
      NO_SERVICE_AND_NAME_STR "at\n" IP46_STR PORT_STR)
{
	/* If this command is run on the 'server' node, it produces an empty unit name and serves as wildcard for all
	 * MSCs. If on a 'server' / 'msc' node, set services only for that MSC Unit Name. */
	struct mslookup_server_msc_cfg *msc = msc_from_node(vty);
	const char *service = argv[0];
	const char *ip_str = argv[1];
	const char *port_str = argv[2];
	struct osmo_sockaddr_str addr;

	if (!msc) {
		vty_out(vty, "%% Error: no MSC object on this node%s", VTY_NEWLINE);
		return CMD_WARNING;
	}

	if (osmo_sockaddr_str_from_str(&addr, ip_str, atoi(port_str))
	    || !osmo_sockaddr_str_is_nonzero(&addr)) {
		vty_out(vty, "%% mslookup server: Invalid address for 'no service' %s: %s %s%s",
			service, ip_str, port_str, VTY_NEWLINE);
		return CMD_WARNING;
	}

	if (mslookup_server_msc_service_del(msc, service, &addr) < 1) {
		vty_out(vty, "%% mslookup server: cannot remove service '%s' to %s %s%s",
			service, ip_str, port_str, VTY_NEWLINE);
		return CMD_WARNING;
	}
	return CMD_SUCCESS;
}

void config_write_msc_services(struct vty *vty, const char *indent, struct mslookup_server_msc_cfg *msc)
{
	struct mslookup_service_host *e;

	llist_for_each_entry(e, &msc->service_hosts, entry) {
		if (osmo_sockaddr_str_is_nonzero(&e->host_v4))
			vty_out(vty, "%sservice %s at %s %u%s", indent, e->service, e->host_v4.ip, e->host_v4.port,
				VTY_NEWLINE);
		if (osmo_sockaddr_str_is_nonzero(&e->host_v6))
			vty_out(vty, "%sservice %s at %s %u%s", indent, e->service, e->host_v6.ip, e->host_v6.port,
				VTY_NEWLINE);
	}
}

int config_write_mslookup(struct vty *vty)
{
	if (!g_hlr->mslookup.server.enable
	    && llist_empty(&g_hlr->mslookup.server.local_site_services))
		return CMD_SUCCESS;

	vty_out(vty, "mslookup%s", VTY_NEWLINE);

	if (g_hlr->mslookup.server.enable || !llist_empty(&g_hlr->mslookup.server.local_site_services)) {
		struct mslookup_server_msc_cfg *msc;

		vty_out(vty, " server%s", VTY_NEWLINE);

		if (g_hlr->mslookup.server.mdns.enable) {
			vty_out(vty, "  mdns bind");
			if (osmo_sockaddr_str_is_nonzero(&g_hlr->mslookup.server.mdns.bind_addr)) {
				vty_out(vty, " %s %u",
					g_hlr->mslookup.server.mdns.bind_addr.ip,
					g_hlr->mslookup.server.mdns.bind_addr.port);
			}
			vty_out(vty, "%s", VTY_NEWLINE);
		}
		if (strcmp(g_hlr->mslookup.server.mdns.domain_suffix, OSMO_MDNS_DOMAIN_SUFFIX_DEFAULT))
			vty_out(vty, "  mdns domain-suffix %s%s",
				g_hlr->mslookup.server.mdns.domain_suffix,
				VTY_NEWLINE);

		msc = mslookup_server_msc_get(&mslookup_server_msc_wildcard, false);
		if (msc)
			config_write_msc_services(vty, " ", msc);

		llist_for_each_entry(msc, &g_hlr->mslookup.server.local_site_services, entry) {
			if (!osmo_ipa_name_cmp(&mslookup_server_msc_wildcard, &msc->name))
				continue;
			vty_out(vty, " msc %s%s", osmo_ipa_name_to_str(&msc->name), VTY_NEWLINE);
			config_write_msc_services(vty, "  ", msc);
		}

		/* If the server is disabled, still output the above to not lose the service config. */
		if (!g_hlr->mslookup.server.enable)
			vty_out(vty, " no server%s", VTY_NEWLINE);
	}

	return CMD_SUCCESS;
}

DEFUN(do_mslookup_show_services,
      do_mslookup_show_services_cmd,
      "show mslookup services",
      SHOW_STR "Distributed GSM / mslookup related information\n"
      "List configured service addresses as sent to remote mslookup requests\n")
{
	struct mslookup_server_msc_cfg *msc;
	const struct mslookup_service_host *local_hlr = mslookup_server_get_local_gsup_addr();

	vty_out(vty, "Local GSUP HLR address returned in mslookup responses for local IMSIs:");
	if (osmo_sockaddr_str_is_nonzero(&local_hlr->host_v4))
		vty_out(vty, " " OSMO_SOCKADDR_STR_FMT,
			OSMO_SOCKADDR_STR_FMT_ARGS(&local_hlr->host_v4));
	if (osmo_sockaddr_str_is_nonzero(&local_hlr->host_v6))
		vty_out(vty, " " OSMO_SOCKADDR_STR_FMT,
			OSMO_SOCKADDR_STR_FMT_ARGS(&local_hlr->host_v6));
	vty_out(vty, "%s", VTY_NEWLINE);

	msc = mslookup_server_msc_get(&mslookup_server_msc_wildcard, false);
	if (msc)
		config_write_msc_services(vty, "", msc);

	llist_for_each_entry(msc, &g_hlr->mslookup.server.local_site_services, entry) {
		if (!osmo_ipa_name_cmp(&mslookup_server_msc_wildcard, &msc->name))
			continue;
		vty_out(vty, "msc ipa-name %s%s", osmo_ipa_name_to_str(&msc->name), VTY_NEWLINE);
		config_write_msc_services(vty, " ", msc);
	}
	return CMD_SUCCESS;
}

void dgsm_vty_init(void)
{
	install_element(CONFIG_NODE, &cfg_mslookup_cmd);

	install_node(&mslookup_node, config_write_mslookup);
	install_element(MSLOOKUP_NODE, &cfg_mslookup_server_cmd);
	install_element(MSLOOKUP_NODE, &cfg_mslookup_no_server_cmd);

	install_node(&mslookup_server_node, NULL);
	install_element(MSLOOKUP_SERVER_NODE, &cfg_mslookup_server_mdns_bind_cmd);
	install_element(MSLOOKUP_SERVER_NODE, &cfg_mslookup_server_mdns_domain_suffix_cmd);
	install_element(MSLOOKUP_SERVER_NODE, &cfg_mslookup_server_no_mdns_bind_cmd);
	install_element(MSLOOKUP_SERVER_NODE, &cfg_mslookup_server_msc_service_cmd);
	install_element(MSLOOKUP_SERVER_NODE, &cfg_mslookup_server_msc_no_service_cmd);
	install_element(MSLOOKUP_SERVER_NODE, &cfg_mslookup_server_msc_no_service_addr_cmd);
	install_element(MSLOOKUP_SERVER_NODE, &cfg_mslookup_server_msc_cmd);

	install_node(&mslookup_server_msc_node, NULL);
	install_element(MSLOOKUP_SERVER_MSC_NODE, &cfg_mslookup_server_msc_service_cmd);
	install_element(MSLOOKUP_SERVER_MSC_NODE, &cfg_mslookup_server_msc_no_service_cmd);
	install_element(MSLOOKUP_SERVER_MSC_NODE, &cfg_mslookup_server_msc_no_service_addr_cmd);

	install_element_ve(&do_mslookup_show_services_cmd);
}
