/* (C) 2018-2019 by sysmocom s.f.m.c. GmbH
 * All Rights Reserved
 *
 * Author: Harald Welte, Philipp Maier
 *
 * 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/core/utils.h>
#include <osmocom/core/fsm.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/vlr_sgs.h>
#include <osmocom/msc/paging.h>

#include "vlr_sgs_fsm.h"
#include "vlr_core.h"

#define S(x) (1 << (x))

static const struct value_string sgs_ue_fsm_event_names[] = {
	{SGS_UE_E_VLR_FAILURE, "VLR_FAILURE"},
	{SGS_UE_E_RX_RESET_FROM_MME, "RX_RESET_FROM_MME"},
	{SGS_UE_E_RX_DETACH_IND_FROM_MME, "RX_DETACH_IND_FROM_MME"},
	{SGS_UE_E_RX_DETACH_IND_FROM_UE, "RX_DETACH_IND_FROM_UE"},	/* vlr.c */
	{SGS_UE_E_RX_LU_FROM_A_IU_GS, "RX_LU_FROM_A_Iu_Gs"},	/* vlr_lu_fsm.c */
	{SGS_UE_E_RX_PAGING_FAILURE, "RX_PAGING_FAILURE"},
	{SGS_UE_E_RX_ALERT_FAILURE, "RX_ALERT_FAILURE"},
	{SGS_UE_E_RX_LU_FROM_MME, "RX_LU_FROM_MME"},
	{SGS_UE_E_TX_LU_REJECT, "TX_LU_REJECT"},
	{SGS_UE_E_TX_LU_ACCEPT, "TX_LU_ACCEPT"},
	{SGS_UE_E_TX_PAGING, "TX_PAGING"},
	{SGS_UE_E_RX_SGSAP_UE_UNREACHABLE, "RX_SGSAP_UE_UNREACH"},
	{SGS_UE_E_RX_TMSI_REALLOC, "RX_TMSI_REALLOC"},
	{0, NULL}
};

/* Initiate location update and change to SGS_UE_ST_LA_UPD_PRES state */
static void perform_lu(struct osmo_fsm_inst *fi)
{
	struct vlr_subscr *vsub = fi->priv;
	int rc;
	osmo_fsm_inst_state_chg(fi, SGS_UE_ST_LA_UPD_PRES, 0, 0);
	vsub->ms_not_reachable_flag = false;

	/* Note: At the moment we allocate a new TMSI on each LU. */
	rc = vlr_subscr_alloc_tmsi(vsub);
	if (rc != 0)
		LOGPFSML(fi, LOGL_ERROR, "(sub %s) VLR LU tmsi allocation failed\n", vlr_subscr_name(vsub));

	rc = vlr_subscr_req_lu(vsub);
	if (rc != 0)
		LOGPFSML(fi, LOGL_ERROR, "(sub %s) HLR LU request failed\n", vlr_subscr_name(vsub));
}

/* Send the SGs Association to NULL state immediately */
static void to_null(struct osmo_fsm_inst *fi)
{
	struct vlr_subscr *vsub = fi->priv;
	osmo_fsm_inst_state_chg(fi, SGS_UE_ST_NULL, 0, 0);

	/* Note: This is only relevent for cases where we are in the middle
	 * of an TMSI reallocation procedure. Should a failure of some sort
	 * put us to NULL state, we have to free the pending TMSI */
	vsub->tmsi_new = GSM_RESERVED_TMSI;

	/* Make sure any ongoing paging is aborted. */
	if (vsub->cs.is_paging)
		paging_expired(vsub);

	/* Ensure that Ts5 (pending paging via SGs) is deleted */
	if (vlr_sgs_pag_pend(vsub))
		osmo_timer_del(&vsub->sgs.Ts5);
}

/* Respawn a pending paging (Timer is reset and a new paging request is sent) */
static void respawn_paging(struct vlr_subscr *vsub)
{
	if (vlr_sgs_pag_pend(vsub)) {

		/* Delete the old paging timer first. */
		osmo_timer_del(&vsub->sgs.Ts5);

		/* Issue a fresh paging request */
		vsub->sgs.paging_cb(vsub, vsub->sgs.paging_serv_ind);
	}
}

/* Figure 4.2.2.1 SGs-NULL */
static void sgs_ue_fsm_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	switch (event) {
	case SGS_UE_E_RX_LU_FROM_MME:
		perform_lu(fi);
		break;
	case SGS_UE_E_TX_PAGING:
		/* do nothing */
		break;
	case SGS_UE_E_RX_PAGING_FAILURE:
		/* do nothing */
		break;
	default:
		OSMO_ASSERT(0);
	}
}

/* Figure 4.2.2.1 SGs-LA-UPDATE-PRESENT */
static void sgs_ue_fsm_lau_present(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct vlr_subscr *vsub = fi->priv;
	enum sgsap_sgs_cause *cause = NULL;

	switch (event) {
	case SGS_UE_E_TX_LU_ACCEPT:
		vsub->conf_by_radio_contact_ind = true;
		vsub->sub_dataconf_by_hlr_ind = true;
		vsub->loc_conf_in_hlr_ind = true;
		vsub->la_allowed = true;
		vsub->imsi_detached_flag = false;

		if (!vsub->lu_complete) {
			vsub->lu_complete = true;
			/* Balanced by vlr_subscr_expire() */
			vlr_subscr_get(vsub, VSUB_USE_ATTACHED);
		}

		vlr_sgs_fsm_update_id(vsub);
		vsub->cs.attached_via_ran = OSMO_RAT_EUTRAN_SGS;

		/* Check if we expect a TMSI REALLOCATION COMPLETE message from the MME
		 * by checking the tmsi_new flag. If this flag is not GSM_RESERVED_TMSI
		 * we know that we have a TMSI pending and need to wait for the MME
		 * to acknowlege first */
		if (vsub->tmsi_new != GSM_RESERVED_TMSI) {
			osmo_fsm_inst_state_chg(fi, SGS_UE_ST_ASSOCIATED, vsub->sgs.cfg.timer[SGS_STATE_TS6_2],
						SGS_STATE_TS6_2);
		} else {
			/* Trigger sending of an MM information request */
			vsub->sgs.mminfo_cb(vsub);

			/* In cases where the LU has interrupted the paging, respawn the paging now,
			 * See also: 3GPP TS 29.118, chapter 5.2.3.2 Location update response */
			if (vlr_sgs_pag_pend(vsub))
				respawn_paging(vsub);

			osmo_fsm_inst_state_chg(fi, SGS_UE_ST_ASSOCIATED, 0, 0);
		}

		break;
	case SGS_UE_E_RX_PAGING_FAILURE:
		cause = data;
		if (*cause == SGSAP_SGS_CAUSE_MT_CSFB_REJ_USER)
			break;
		to_null(fi);
		break;
	case SGS_UE_E_TX_LU_REJECT:
	case SGS_UE_E_RX_ALERT_FAILURE:
		to_null(fi);
		break;
	case SGS_UE_E_TX_PAGING:
		/* do nothing */
		break;
	default:
		OSMO_ASSERT(0);
		break;
	}
}

/* Figure 4.2.2.1 SGs-ASSOCIATED */
static void sgs_ue_fsm_associated(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct vlr_subscr *vsub = fi->priv;
	enum sgsap_sgs_cause *cause = NULL;

	switch (event) {
	case SGS_UE_E_TX_PAGING:
		/* do nothing */
		break;
	case SGS_UE_E_RX_TMSI_REALLOC:
		if (vsub->tmsi_new == GSM_RESERVED_TMSI) {
			LOGPFSML(fi, LOGL_ERROR,
				 "(sub %s) TMSI reallocation completed at the MME, but no TMSI reallocation ordered.\n",
				 vlr_subscr_msisdn_or_name(vsub));
		}

		vsub->tmsi = vsub->tmsi_new;
		vsub->tmsi_new = GSM_RESERVED_TMSI;

		/* Trigger sending of MM information */
		vsub->sgs.mminfo_cb(vsub);

		/* In cases where the LU has interrupted the paging, respawn the paging now,
		 * See also: 3GPP TS 29.118, chapter 5.2.3.2 Location update response */
		if (vlr_sgs_pag_pend(vsub))
			respawn_paging(vsub);

		/* Note: We are already in SGS_UE_ST_ASSOCIATED but the
		 * transition that lead us here had is guarded with Ts6-1,
		 * wo we change the state now once more without timeout
		 * to ensure the timer is stopped */
		osmo_fsm_inst_state_chg(fi, SGS_UE_ST_ASSOCIATED, 0, 0);
		break;
	case SGS_UE_E_RX_SGSAP_UE_UNREACHABLE:
		/* do nothing */
		break;
	case SGS_UE_E_RX_PAGING_FAILURE:
		cause = data;
		if (*cause == SGSAP_SGS_CAUSE_MT_CSFB_REJ_USER)
			break;
		to_null(fi);
	case SGS_UE_E_RX_ALERT_FAILURE:
		to_null(fi);
		break;
	case SGS_UE_E_RX_LU_FROM_MME:
		perform_lu(fi);
		break;
	default:
		OSMO_ASSERT(0);
		break;
	}
}

/* Figure 4.2.2.1 From any of the three states (at the VLR) */
static void sgs_ue_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct vlr_subscr *vsub = fi->priv;

	switch (event) {
	case SGS_UE_E_RX_DETACH_IND_FROM_MME:
	case SGS_UE_E_RX_DETACH_IND_FROM_UE:
		vsub->imsi_detached_flag = true;
		vsub->expire_lu = VLR_SUBSCRIBER_NO_EXPIRATION;
		/* See 5.4.3 and 5.5.3 */
		to_null(fi);
		break;
	case SGS_UE_E_RX_RESET_FROM_MME:
		/* See also 3GPP TS 29.118, chapter 5.7.2.1 VLR Reset Initiation */
		vsub->conf_by_radio_contact_ind = false;
		to_null(fi);
		break;
	case SGS_UE_E_VLR_FAILURE:
	case SGS_UE_E_RX_LU_FROM_A_IU_GS:
		to_null(fi);
		break;
	default:
		OSMO_ASSERT(0);
		break;
	}
}

static int sgs_ue_fsm_timer_cb(struct osmo_fsm_inst *fi)
{
	struct vlr_subscr *vsub = fi->priv;
	switch (fi->T) {

	case SGS_STATE_TS6_2:
		/* Failed TMSI reallocation procedure, deallocate all TMSI
		 * information, but don't change the SGs association state. */
		vsub->tmsi_new = GSM_RESERVED_TMSI;
		vsub->tmsi = GSM_RESERVED_TMSI;
		break;
	default:
		/* Unhandled timer */
		OSMO_ASSERT(false);
		break;
	}
	return 0;
}

static const struct osmo_fsm_state sgs_ue_fsm_states[] = {
	[SGS_UE_ST_NULL] = {
		.name = "SGs-NULL",
		.action = sgs_ue_fsm_null,
		.in_event_mask = 0
			| S(SGS_UE_E_RX_LU_FROM_MME)
			| S(SGS_UE_E_TX_PAGING)
			| S(SGS_UE_E_RX_PAGING_FAILURE)
			,
		.out_state_mask = 0
			| S(SGS_UE_ST_NULL)
			| S(SGS_UE_ST_LA_UPD_PRES)
			,
	},
	[SGS_UE_ST_LA_UPD_PRES] = {
		.name = "SGs-LA-UPDATE-PRESENT",
		.action = sgs_ue_fsm_lau_present,
		.in_event_mask = 0
			| S(SGS_UE_E_TX_LU_ACCEPT)
			| S(SGS_UE_E_TX_LU_REJECT)
			| S(SGS_UE_E_TX_PAGING)
			| S(SGS_UE_E_RX_PAGING_FAILURE)
			| S(SGS_UE_E_RX_ALERT_FAILURE)
			,
		.out_state_mask = 0
			| S(SGS_UE_ST_NULL)
			| S(SGS_UE_ST_ASSOCIATED)
			| S(SGS_UE_ST_LA_UPD_PRES)
			,
	},
	[SGS_UE_ST_ASSOCIATED] = {
		.name = "SGs-ASSOCIATED",
		.action = sgs_ue_fsm_associated,
		.in_event_mask = 0
			| S(SGS_UE_E_TX_PAGING)
			| S(SGS_UE_E_RX_TMSI_REALLOC)
			| S(SGS_UE_E_RX_SGSAP_UE_UNREACHABLE)
			| S(SGS_UE_E_RX_PAGING_FAILURE)
			| S(SGS_UE_E_RX_ALERT_FAILURE)
			| S(SGS_UE_E_RX_LU_FROM_MME)
			,
		.out_state_mask = 0
			| S(SGS_UE_ST_NULL)
			| S(SGS_UE_ST_ASSOCIATED)
			| S(SGS_UE_ST_LA_UPD_PRES)
			,
	},
};

static struct osmo_fsm sgs_ue_fsm = {
	.name = "SGs-UE",
	.states = sgs_ue_fsm_states,
	.num_states = ARRAY_SIZE(sgs_ue_fsm_states),
	.allstate_event_mask = S(SGS_UE_E_RX_RESET_FROM_MME) |
		S(SGS_UE_E_VLR_FAILURE) | S(SGS_UE_E_RX_DETACH_IND_FROM_MME) | S(SGS_UE_E_RX_DETACH_IND_FROM_UE) |
		S(SGS_UE_E_RX_LU_FROM_A_IU_GS),
	.allstate_action = sgs_ue_fsm_allstate,
	.timer_cb = sgs_ue_fsm_timer_cb,
	.log_subsys = DSGS,
	.event_names = sgs_ue_fsm_event_names,
};

/*! Initalize/Register SGs FSM in osmo-fsm subsystem */
void vlr_sgs_fsm_init(void)
{
	if (osmo_fsm_find_by_name(sgs_ue_fsm.name) != &sgs_ue_fsm)
		OSMO_ASSERT(osmo_fsm_register(&sgs_ue_fsm) == 0);
}

/*! Crate SGs FSM in struct vlr_subscr.
 *  \param[in] vsub VLR subscriber for which the SGs FSM should be created. */
void vlr_sgs_fsm_create(struct vlr_subscr *vsub)
{
	char interim_fsm_id[256];
	static unsigned int fsm_id_num = 0;

	/* An SGSs FSM must not be created twice! */
	OSMO_ASSERT(!vsub->sgs_fsm);

	snprintf(interim_fsm_id, sizeof(interim_fsm_id), "num:%u", fsm_id_num);

	vsub->sgs_fsm = osmo_fsm_inst_alloc(&sgs_ue_fsm, vsub, vsub, LOGL_INFO, interim_fsm_id);
	OSMO_ASSERT(vsub->sgs_fsm);

	osmo_fsm_inst_state_chg(vsub->sgs_fsm, SGS_UE_ST_NULL, 0, 0);

	fsm_id_num++;
}

/*! Remove SGs FSM from struct vlr_subscr.
 *  \param[in] vsub VLR subscriber from which the SGs FSM should be removed. */
void vlr_sgs_fsm_remove(struct vlr_subscr *vsub)
{
	/* An SGSs FSM must exist! */
	OSMO_ASSERT(vsub->sgs_fsm);

	osmo_fsm_inst_state_chg(vsub->sgs_fsm, SGS_UE_ST_NULL, 0, 0);
	osmo_fsm_inst_term(vsub->sgs_fsm, OSMO_FSM_TERM_REGULAR, NULL);
	vsub->sgs_fsm = NULL;
}

/*! Update the ID of the SGs FSM with the subscriber IMSI
 *  \param[in] vsub VLR subscriber to update. */
void vlr_sgs_fsm_update_id(struct vlr_subscr *vsub)
{
	char fsm_id[256];

	if (strlen(vsub->imsi) > 0) {
		snprintf(fsm_id, sizeof(fsm_id), "imsi:%s", vsub->imsi);
		osmo_fsm_inst_update_id(vsub->sgs_fsm, fsm_id);
	}
}
