/* 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 <string.h>
#include <errno.h>
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/gsm/gsup.h>
#include <osmocom/mslookup/mslookup.h>
#include <osmocom/hlr/logging.h>
#include <osmocom/hlr/hlr.h>
#include <osmocom/hlr/db.h>
#include <osmocom/hlr/timestamp.h>
#include <osmocom/hlr/mslookup_server.h>
#include <osmocom/hlr/proxy.h>

static const struct osmo_mslookup_result not_found = {
		.rc = OSMO_MSLOOKUP_RC_NOT_FOUND,
	};
const struct osmo_ipa_name mslookup_server_msc_wildcard = {};

static void set_result(struct osmo_mslookup_result *result,
		       const struct mslookup_service_host *service_host,
		       uint32_t age)
{
	if (!osmo_sockaddr_str_is_nonzero(&service_host->host_v4)
	    && !osmo_sockaddr_str_is_nonzero(&service_host->host_v6)) {
		*result = not_found;
		return;
	}
	result->rc = OSMO_MSLOOKUP_RC_RESULT;
	result->host_v4 = service_host->host_v4;
	result->host_v6 = service_host->host_v6;
	result->age = age;
}

const struct mslookup_service_host *mslookup_server_get_local_gsup_addr(void)
{
	static struct mslookup_service_host gsup_bind = {};
	struct mslookup_service_host *host;

	/* Find a HLR/GSUP service set for the server (no VLR unit name) */
	host = mslookup_server_service_get(&mslookup_server_msc_wildcard, OSMO_MSLOOKUP_SERVICE_HLR_GSUP);
	if (host)
		return host;

	/* Try to use the locally configured GSUP bind address */
	osmo_sockaddr_str_from_str(&gsup_bind.host_v4, g_hlr->gsup_bind_addr, OSMO_GSUP_PORT);
	if (gsup_bind.host_v4.af == AF_INET6) {
		gsup_bind.host_v6 = gsup_bind.host_v4;
		gsup_bind.host_v4 = (struct osmo_sockaddr_str){};
	}
	return &gsup_bind;
}

struct mslookup_server_msc_cfg *mslookup_server_msc_get(const struct osmo_ipa_name *msc_name, bool create)
{
	struct llist_head *c = &g_hlr->mslookup.server.local_site_services;
	struct mslookup_server_msc_cfg *msc;

	if (!msc_name)
		return NULL;

	llist_for_each_entry(msc, c, entry) {
		if (osmo_ipa_name_cmp(&msc->name, msc_name))
			continue;
		return msc;
	}
	if (!create)
		return NULL;

	msc = talloc_zero(g_hlr, struct mslookup_server_msc_cfg);
	OSMO_ASSERT(msc);
	INIT_LLIST_HEAD(&msc->service_hosts);
	msc->name = *msc_name;
	llist_add_tail(&msc->entry, c);
	return msc;
}

struct mslookup_service_host *mslookup_server_msc_service_get(struct mslookup_server_msc_cfg *msc, const char *service,
							      bool create)
{
	struct mslookup_service_host *e;
	if (!msc)
		return NULL;

	llist_for_each_entry(e, &msc->service_hosts, entry) {
		if (!strcmp(e->service, service))
			return e;
	}

	if (!create)
		return NULL;

	e = talloc_zero(msc, struct mslookup_service_host);
	OSMO_ASSERT(e);
	OSMO_STRLCPY_ARRAY(e->service, service);
	llist_add_tail(&e->entry, &msc->service_hosts);
	return e;
}

struct mslookup_service_host *mslookup_server_service_get(const struct osmo_ipa_name *msc_name, const char *service)
{
	struct mslookup_server_msc_cfg *msc = mslookup_server_msc_get(msc_name, false);
	if (!msc)
		return NULL;
	return mslookup_server_msc_service_get(msc, service, false);
}

int mslookup_server_msc_service_set(struct mslookup_server_msc_cfg *msc, const char *service,
				    const struct osmo_sockaddr_str *addr)
{
	struct mslookup_service_host *e;

	if (!service || !service[0]
	    || strlen(service) > OSMO_MSLOOKUP_SERVICE_MAXLEN)
		return -EINVAL;
	if (!addr || !osmo_sockaddr_str_is_nonzero(addr))
		return -EINVAL;

	e = mslookup_server_msc_service_get(msc, service, true);
	if (!e)
		return -EINVAL;

	switch (addr->af) {
	case AF_INET:
		e->host_v4 = *addr;
		break;
	case AF_INET6:
		e->host_v6 = *addr;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

int mslookup_server_msc_service_del(struct mslookup_server_msc_cfg *msc, const char *service,
				    const struct osmo_sockaddr_str *addr)
{
	struct mslookup_service_host *e, *n;
	int deleted = 0;

	if (!msc)
		return -ENOENT;

	llist_for_each_entry_safe(e, n, &msc->service_hosts, entry) {
		if (service && strcmp(service, e->service))
			continue;

		if (addr) {
			if (!osmo_sockaddr_str_cmp(addr, &e->host_v4)) {
				e->host_v4 = (struct osmo_sockaddr_str){};
				/* Removed one addr. If the other is still there, keep the entry. */
				if (osmo_sockaddr_str_is_nonzero(&e->host_v6))
					continue;
			} else if (!osmo_sockaddr_str_cmp(addr, &e->host_v6)) {
				e->host_v6 = (struct osmo_sockaddr_str){};
				/* Removed one addr. If the other is still there, keep the entry. */
				if (osmo_sockaddr_str_is_nonzero(&e->host_v4))
					continue;
			} else
				/* No addr match, keep the entry. */
				continue;
			/* Addr matched and none is left. Delete. */
		}
		llist_del(&e->entry);
		talloc_free(e);
		deleted++;
	}
	return deleted;
}

/* A remote entity is asking us whether we are the home HLR of the given subscriber. */
static void mslookup_server_rx_hlr_gsup(const struct osmo_mslookup_query *query,
					struct osmo_mslookup_result *result)
{
	const struct mslookup_service_host *host;
	int rc;
	switch (query->id.type) {
	case OSMO_MSLOOKUP_ID_IMSI:
		rc = db_subscr_exists_by_imsi(g_hlr->dbc, query->id.imsi);
		break;
	case OSMO_MSLOOKUP_ID_MSISDN:
		rc = db_subscr_exists_by_msisdn(g_hlr->dbc, query->id.msisdn);
		break;
	default:
		LOGP(DMSLOOKUP, LOGL_ERROR, "Unknown mslookup ID type: %d\n", query->id.type);
		*result = not_found;
		return;
	}

	if (rc) {
		LOGP(DMSLOOKUP, LOGL_DEBUG, "%s: does not exist in local HLR\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL));
		*result = not_found;
		return;
	}

	LOGP(DMSLOOKUP, LOGL_DEBUG, "%s: found in local HLR\n",
	     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL));

	host = mslookup_server_get_local_gsup_addr();

	set_result(result, host, 0);
	if (result->rc != OSMO_MSLOOKUP_RC_RESULT) {
		LOGP(DMSLOOKUP, LOGL_ERROR,
		     "Subscriber found, but error in service '" OSMO_MSLOOKUP_SERVICE_HLR_GSUP "' config:"
		     " v4: " OSMO_SOCKADDR_STR_FMT "  v6: " OSMO_SOCKADDR_STR_FMT "\n",
		     OSMO_SOCKADDR_STR_FMT_ARGS(&host->host_v4),
		     OSMO_SOCKADDR_STR_FMT_ARGS(&host->host_v6));
	}
}

/* Look in the local HLR record: If the subscriber is "at home" in this HLR and is also currently located at a local
 * VLR, we will find a valid location updating with vlr_number, and no vlr_via_proxy entry. */
static bool subscriber_has_done_lu_here_hlr(const struct osmo_mslookup_query *query,
					    uint32_t *lu_age,
					    struct osmo_ipa_name *local_msc_name,
					    struct hlr_subscriber *ret_subscr)
{
	struct hlr_subscriber _subscr;
	int rc;
	uint32_t age;

	struct hlr_subscriber *subscr = ret_subscr ? : &_subscr;

	switch (query->id.type) {
	case OSMO_MSLOOKUP_ID_IMSI:
		rc = db_subscr_get_by_imsi(g_hlr->dbc, query->id.imsi, subscr);
		break;
	case OSMO_MSLOOKUP_ID_MSISDN:
		rc = db_subscr_get_by_msisdn(g_hlr->dbc, query->id.msisdn, subscr);
		break;
	default:
		LOGP(DMSLOOKUP, LOGL_ERROR, "Unknown mslookup ID type: %d\n", query->id.type);
		return false;
	}

	if (rc) {
		LOGP(DMSLOOKUP, LOGL_DEBUG, "%s: does not exist in local HLR\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL));
		return false;
	}

	if (!subscr->vlr_number[0]) {
		LOGP(DMSLOOKUP, LOGL_DEBUG, "%s: not attached (vlr_number unset)\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL));
		return false;
	}

	if (subscr->vlr_via_proxy.len) {
		/* The VLR is behind a proxy, the subscriber is not attached to a local VLR but a remote one. That
		 * remote proxy should instead respond to the service lookup request. */
		LOGP(DMSLOOKUP, LOGL_DEBUG, "%s: last attach is not at local VLR, but at VLR '%s' via proxy %s\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL),
		     subscr->vlr_number,
		     osmo_ipa_name_to_str(&subscr->vlr_via_proxy));
		return false;
	}

	if (!timestamp_age(&subscr->last_lu_seen, &age)) {
		LOGP(DMSLOOKUP, LOGL_DEBUG, "%s: Invalid last_lu_seen timestamp for subscriber\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL));
		return false;
	}
	if (age > g_hlr->mslookup.server.local_attach_max_age) {
		LOGP(DMSLOOKUP, LOGL_DEBUG, "%s: last attach was here, but too long ago: %us > %us\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL),
		     age, g_hlr->mslookup.server.local_attach_max_age);
		return false;
	}

	*lu_age = age;
	osmo_ipa_name_set_str(local_msc_name, subscr->vlr_number);
	LOGP(DMSLOOKUP, LOGL_DEBUG, "%s: attached %u seconds ago at local VLR %s\n",
	     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL),
	     age, osmo_ipa_name_to_str(local_msc_name));

	return true;
}


/* Determine whether the subscriber with the given ID has routed a Location Updating via this HLR as first hop. Return
 * true if it is attached at a local VLR, and we are serving as proxy for a remote home HLR.
 */
static bool subscriber_has_done_lu_here_proxy(const struct osmo_mslookup_query *query,
					      uint32_t *lu_age,
					      struct osmo_ipa_name *local_msc_name,
					      struct proxy_subscr *ret_proxy_subscr)
{
	struct proxy_subscr proxy_subscr;
	uint32_t age;
	int rc;

	/* See the local HLR record. If the subscriber is "at home" in this HLR and is also currently located here, we
	 * will find a valid location updating and no vlr_via_proxy entry. */
	switch (query->id.type) {
	case OSMO_MSLOOKUP_ID_IMSI:
		rc = proxy_subscr_get_by_imsi(&proxy_subscr, g_hlr->gs->proxy, query->id.imsi);
		break;
	case OSMO_MSLOOKUP_ID_MSISDN:
		rc = proxy_subscr_get_by_msisdn(&proxy_subscr, g_hlr->gs->proxy, query->id.msisdn);
		break;
	default:
		LOGP(DDGSM, LOGL_ERROR, "%s: unknown ID type\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL));
		return false;
	}

	if (rc) {
		LOGP(DDGSM, LOGL_DEBUG, "%s: does not exist in GSUP proxy\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL));
		return false;
	}

	/* We only need to care about CS LU, since only CS services need D-GSM routing. */
	if (!timestamp_age(&proxy_subscr.cs.last_lu, &age)
	    || age > g_hlr->mslookup.server.local_attach_max_age) {
		LOGP(DDGSM, LOGL_ERROR,
		     "%s: last attach was at local VLR (proxying for remote HLR), but too long ago: %us > %us\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL),
		     age, g_hlr->mslookup.server.local_attach_max_age);
		return false;
	}

	if (proxy_subscr.cs.vlr_via_proxy.len) {
		LOGP(DDGSM, LOGL_DEBUG, "%s: last attach is not at local VLR, but at VLR '%s' via proxy '%s'\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL),
		     osmo_ipa_name_to_str(&proxy_subscr.cs.vlr_name),
		     osmo_ipa_name_to_str(&proxy_subscr.cs.vlr_via_proxy));
		return false;
	}

	*lu_age = age;
	*local_msc_name = proxy_subscr.cs.vlr_name;
	LOGP(DDGSM, LOGL_DEBUG, "%s: attached %u seconds ago at local VLR %s; proxying for remote HLR "
	     OSMO_SOCKADDR_STR_FMT "\n",
	     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL),
	     age, osmo_ipa_name_to_str(local_msc_name),
	     OSMO_SOCKADDR_STR_FMT_ARGS(&proxy_subscr.remote_hlr_addr));

	if (ret_proxy_subscr)
		*ret_proxy_subscr = proxy_subscr;
	return true;
}

bool subscriber_has_done_lu_here(const struct osmo_mslookup_query *query,
				 uint32_t *lu_age_p, struct osmo_ipa_name *local_msc_name,
				 char *ret_imsi, size_t ret_imsi_len)
{
	bool attached_here;
	uint32_t lu_age = 0;
	struct osmo_ipa_name msc_name = {};
	bool attached_here_proxy;
	uint32_t proxy_lu_age = 0;
	struct osmo_ipa_name proxy_msc_name = {};
	struct proxy_subscr proxy_subscr;
	struct hlr_subscriber db_subscr;


	/* First ask the local HLR db, but if the local proxy record indicates a more recent LU, use that instead.
	 * For all usual cases, only one of these will reflect a LU, even if a subscriber had more than one home HLR:
	 *   - if the subscriber is known here, we will never proxy.
	 *   - if the subscriber is not known here, this local HLR db will never record a LU.
	 * However, if a subscriber was being proxied to a remote home HLR, and if then the subscriber was also added to
	 * the local HLR database, there might occur a situation where both reflect a LU. So, to be safe against all
	 * situations, compare the two entries.
	 */
	attached_here = subscriber_has_done_lu_here_hlr(query, &lu_age, &msc_name, &db_subscr);
	attached_here_proxy = subscriber_has_done_lu_here_proxy(query, &proxy_lu_age, &proxy_msc_name, &proxy_subscr);

	/* If proxy has a younger lu, replace. */
	if (attached_here_proxy && (!attached_here || (proxy_lu_age < lu_age))) {
		attached_here = true;
		lu_age = proxy_lu_age;
		msc_name = proxy_msc_name;
		if (ret_imsi)
			osmo_strlcpy(ret_imsi, proxy_subscr.imsi, ret_imsi_len);
	} else if (attached_here) {
		if (ret_imsi)
			osmo_strlcpy(ret_imsi, db_subscr.imsi, ret_imsi_len);
	}

	if (attached_here && !msc_name.len) {
		LOGP(DMSLOOKUP, LOGL_ERROR, "%s: attached here, but no VLR name known\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL));
		return false;
	}

	if (!attached_here) {
		/* Already logged "not attached" for both local-db and proxy attach */
		return false;
	}

	LOGP(DMSLOOKUP, LOGL_INFO, "%s: attached here, at VLR %s\n",
	     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL),
	     osmo_ipa_name_to_str(&msc_name));
	*lu_age_p = lu_age;
	*local_msc_name = msc_name;
	return true;
}

/* A remote entity is asking us whether we are providing the given service for the given subscriber. */
void mslookup_server_rx(const struct osmo_mslookup_query *query,
			struct osmo_mslookup_result *result)
{
	const struct mslookup_service_host *service_host;
	uint32_t age;
	struct osmo_ipa_name msc_name;

	/* A request for a home HLR: answer exactly if this is the subscriber's home HLR, i.e. the IMSI is listed in the
	 * HLR database. */
	if (strcmp(query->service, OSMO_MSLOOKUP_SERVICE_HLR_GSUP) == 0)
		return mslookup_server_rx_hlr_gsup(query, result);

	/* All other service types: answer when the subscriber has done a LU that is either listed in the local HLR or
	 * in the GSUP proxy database: i.e. if the subscriber has done a Location Updating at an VLR belonging to this
	 * HLR. Respond with whichever services are configured in the osmo-hlr.cfg. */
	if (!subscriber_has_done_lu_here(query, &age, &msc_name, NULL, 0)) {
		*result = not_found;
		return;
	}

	/* We've detected a LU here. The VLR where the LU happened is stored in msc_unit_name, and the LU age is stored
	 * in 'age'. Figure out the address configured for that VLR and service name. */
	service_host = mslookup_server_service_get(&msc_name, query->service);

	if (!service_host) {
		/* Find such service set globally (no VLR unit name) */
		service_host = mslookup_server_service_get(&mslookup_server_msc_wildcard, query->service);
	}

	if (!service_host) {
		LOGP(DMSLOOKUP, LOGL_ERROR,
		     "%s: subscriber found, but no service %s configured, cannot service lookup request\n",
		     osmo_mslookup_result_name_c(OTC_SELECT, query, NULL),
		     osmo_quote_str_c(OTC_SELECT, query->service, -1));
		*result = not_found;
		return;
	}

	set_result(result, service_host, age);
}
