/* 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 <osmocom/gsm/apn.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;
	luop->timer.cb = lu_op_timer_cb;
	luop->timer.data = 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);
	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)
		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 apn[APN_MAXLEN];
	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;

	/* 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 */
		l = osmo_apn_from_str(apn, sizeof(apn), "*");
		if (l > 0) {
			gsup.pdp_infos[0].apn_enc = apn;
			gsup.pdp_infos[0].apn_enc_len = l;
			gsup.pdp_infos[0].have_info = 1;
			gsup.num_pdp_infos = 1;
			/* FIXME: use real value: */
			gsup.pdp_infos[0].context_id = 1;
		}
	}

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