/* OsmoHLR TX/RX lu operations */

/* (C) 2017 sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * Author: Harald Welte <laforge@gnumonks.org>
 *
 * 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 <stdbool.h>
#include <string.h>
#include <errno.h>

#include <osmocom/core/logging.h>
#include <osmocom/gsm/gsm48_ie.h>
#include <osmocom/gsm/gsup.h>

#include "gsup_server.h"
#include "gsup_router.h"
#include "logging.h"
#include "luop.h"

const struct value_string lu_state_names[] = {
	{ LU_S_NULL,			"NULL" },
	{ LU_S_LU_RECEIVED,		"LU RECEIVED" },
	{ LU_S_CANCEL_SENT,		"CANCEL SENT" },
	{ LU_S_CANCEL_ACK_RECEIVED,	"CANCEL-ACK RECEIVED" },
	{ LU_S_ISD_SENT,		"ISD SENT" },
	{ LU_S_ISD_ACK_RECEIVED,	"ISD-ACK RECEIVED" },
	{ LU_S_COMPLETE,		"COMPLETE" },
	{ 0, NULL }
};

/* Transmit a given GSUP message for the given LU operation */
static void _luop_tx_gsup(struct lu_operation *luop,
			  const struct osmo_gsup_message *gsup)
{
	struct msgb *msg_out;

	msg_out = msgb_alloc_headroom(1024+16, 16, "GSUP LUOP");
	osmo_gsup_encode(msg_out, gsup);

	osmo_gsup_addr_send(luop->gsup_server, luop->peer,
			    talloc_total_size(luop->peer),
			    msg_out);
}

static inline void fill_gsup_msg(struct osmo_gsup_message *out,
				 const struct lu_operation *lu,
				 enum osmo_gsup_message_type mt)
{
	memset(out, 0, sizeof(struct osmo_gsup_message));
	if (lu)
		osmo_strlcpy(out->imsi, lu->subscr.imsi,
			     GSM23003_IMSI_MAX_DIGITS + 1);
	out->message_type = mt;
}

/* timer call-back in case LU operation doesn't receive an response */
static void lu_op_timer_cb(void *data)
{
	struct lu_operation *luop = data;

	DEBUGP(DMAIN, "LU OP timer expired in state %s\n",
		get_value_string(lu_state_names, luop->state));

	switch (luop->state) {
	case LU_S_CANCEL_SENT:
		break;
	case LU_S_ISD_SENT:
		break;
	default:
		break;
	}

	lu_op_tx_error(luop, GMM_CAUSE_NET_FAIL);
}

bool lu_op_fill_subscr(struct lu_operation *luop, struct db_context *dbc,
		       const char *imsi)
{
	struct hlr_subscriber *subscr = &luop->subscr;

	if (db_subscr_get_by_imsi(dbc, imsi, subscr) < 0)
		return false;

	return true;
}

struct lu_operation *lu_op_alloc(struct osmo_gsup_server *srv)
{
	struct lu_operation *luop;

	luop = talloc_zero(srv, struct lu_operation);
	OSMO_ASSERT(luop);
	luop->gsup_server = srv;
	osmo_timer_setup(&luop->timer, lu_op_timer_cb, luop);

	return luop;
}

void lu_op_free(struct lu_operation *luop)
{
	/* Only attempt to remove when it was ever added to a list. */
	if (luop->list.next)
		llist_del(&luop->list);

	/* Delete timer just in case it is still pending. */
	osmo_timer_del(&luop->timer);

	talloc_free(luop);
}

struct lu_operation *lu_op_alloc_conn(struct osmo_gsup_conn *conn)
{
	uint8_t *peer_addr;
	struct lu_operation *luop = lu_op_alloc(conn->server);
	int rc = osmo_gsup_conn_ccm_get(conn, &peer_addr, IPAC_IDTAG_SERNR);
	if (rc < 0) {
		lu_op_free(luop);
		return NULL;
	}

	luop->peer = talloc_memdup(luop, peer_addr, rc);

	return luop;
}

/* FIXME: this doesn't seem to work at all */
struct lu_operation *lu_op_by_imsi(const char *imsi,
				   const struct llist_head *lst)
{
	struct lu_operation *luop;

	llist_for_each_entry(luop, lst, list) {
		if (!strcmp(imsi, luop->subscr.imsi))
			return luop;
	}
	return NULL;
}

void lu_op_statechg(struct lu_operation *luop, enum lu_state new_state)
{
	enum lu_state old_state = luop->state;

	DEBUGP(DMAIN, "LU OP state change: %s -> ",
		get_value_string(lu_state_names, old_state));
	DEBUGPC(DMAIN, "%s\n",
		get_value_string(lu_state_names, new_state));

	luop->state = new_state;
}

/* Send a msgb to a given address using routing */
int osmo_gsup_addr_send(struct osmo_gsup_server *gs,
			const uint8_t *addr, size_t addrlen,
			struct msgb *msg)
{
	struct osmo_gsup_conn *conn;

	conn = gsup_route_find(gs, addr, addrlen);
	if (!conn) {
		DEBUGP(DMAIN, "Cannot find route for addr %s\n", addr);
		msgb_free(msg);
		return -ENODEV;
	}

	return osmo_gsup_conn_send(conn, msg);
}

/*! Transmit UPD_LOC_ERROR and destroy lu_operation */
void lu_op_tx_error(struct lu_operation *luop, enum gsm48_gmm_cause cause)
{
	struct osmo_gsup_message gsup;

	DEBUGP(DMAIN, "%s: LU OP Tx Error (cause %s)\n",
	       luop->subscr.imsi, get_value_string(gsm48_gmm_cause_names,
						   cause));

	fill_gsup_msg(&gsup, luop, OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR);
	gsup.cause = cause;

	_luop_tx_gsup(luop, &gsup);

	lu_op_free(luop);
}

/*! Transmit UPD_LOC_RESULT and destroy lu_operation */
void lu_op_tx_ack(struct lu_operation *luop)
{
	struct osmo_gsup_message gsup;

	fill_gsup_msg(&gsup, luop, OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT);
	//FIXME gsup.hlr_enc;

	_luop_tx_gsup(luop, &gsup);

	lu_op_free(luop);
}

/*! Send Cancel Location to old VLR/SGSN */
void lu_op_tx_cancel_old(struct lu_operation *luop)
{
	struct osmo_gsup_message gsup;

	OSMO_ASSERT(luop->state == LU_S_LU_RECEIVED);

	fill_gsup_msg(&gsup, NULL, OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST);
	//gsup.cause = FIXME;
	//gsup.cancel_type = FIXME;

	_luop_tx_gsup(luop, &gsup);

	lu_op_statechg(luop, LU_S_CANCEL_SENT);
	osmo_timer_schedule(&luop->timer, CANCEL_TIMEOUT_SECS, 0);
}

/*! Transmit Insert Subscriber Data to new VLR/SGSN */
void lu_op_tx_insert_subscr_data(struct lu_operation *luop)
{
	struct osmo_gsup_message gsup;
	uint8_t msisdn_enc[43]; /* TODO use constant; TS 24.008 10.5.4.7 */
	int l;

	OSMO_ASSERT(luop->state == LU_S_LU_RECEIVED ||
		    luop->state == LU_S_CANCEL_ACK_RECEIVED);

	fill_gsup_msg(&gsup, luop, OSMO_GSUP_MSGT_INSERT_DATA_REQUEST);

	l = gsm48_encode_bcd_number(msisdn_enc, sizeof(msisdn_enc), 0,
				    luop->subscr.msisdn);
	if (l < 1) {
		LOGP(DMAIN, LOGL_ERROR,
		     "%s: Error: cannot encode MSISDN '%s'\n",
		     luop->subscr.imsi, luop->subscr.msisdn);
		lu_op_tx_error(luop, GMM_CAUSE_PROTO_ERR_UNSPEC);
		return;
	}
	gsup.msisdn_enc = msisdn_enc;
	gsup.msisdn_enc_len = l;

	#pragma message "FIXME: deal with encoding the following data: gsup.hlr_enc"

	if (luop->is_ps) {
		/* FIXME: PDP infos - use more fine-grained access control
		   instead of wildcard APN */
		osmo_gsup_configure_wildcard_apn(&gsup);
	}

	/* Send ISD to new VLR/SGSN */
	_luop_tx_gsup(luop, &gsup);

	lu_op_statechg(luop, LU_S_ISD_SENT);
	osmo_timer_schedule(&luop->timer, ISD_TIMEOUT_SECS, 0);
}

/*! Transmit Delete Subscriber Data to new VLR/SGSN.
 * The luop is not freed. */
void lu_op_tx_del_subscr_data(struct lu_operation *luop)
{
	struct osmo_gsup_message gsup;

	fill_gsup_msg(&gsup, luop, OSMO_GSUP_MSGT_DELETE_DATA_REQUEST);

	gsup.cn_domain = OSMO_GSUP_CN_DOMAIN_PS;

	/* Send ISD to new VLR/SGSN */
	_luop_tx_gsup(luop, &gsup);
}
