/* 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()
{
	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);
}
