/* The MSC-A role implementation variant that forwards requests to/from a remote MSC. */
/*
 * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * SPDX-License-Identifier: AGPL-3.0+
 *
 * Author: Neels Hofmeyr
 *
 * 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 <inttypes.h>

#include <osmocom/core/fsm.h>
#include <osmocom/gsm/gsup.h>

#include <osmocom/msc/debug.h>
#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/msc_a_remote.h>
#include <osmocom/msc/msc_roles.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/msc_a.h>
#include <osmocom/msc/msc_t.h>
#include <osmocom/msc/e_link.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/ran_peer.h>

static struct osmo_fsm msc_a_remote_fsm;

static struct msc_a *msc_a_remote_priv(struct osmo_fsm_inst *fi)
{
	OSMO_ASSERT(fi);
	OSMO_ASSERT(fi->fsm == &msc_a_remote_fsm);
	OSMO_ASSERT(fi->priv);
	return fi->priv;
}

/* The idea is that this msc_a role is event-compatible to the "real" msc_a.c FSM, but instead of acting on the events
 * directly, it forwards the events to a remote MSC-A role, via E-over-GSUP.
 *
 *     [MSC-A---------------------]            [MSC-B---------------------]
 *      msc_a <-- msc_{i,t}_remote <---GSUP---- msc_a_remote <-- msc_{i,t} <--BSSMAP--- [BSS]
 *                                            ^you are here
 */
static int msc_a_remote_msg_up_to_remote_msc(struct msc_a *msc_a,
					     enum msc_role from_role,
					     enum osmo_gsup_message_type message_type,
					     struct an_apdu *an_apdu)
{
	struct osmo_gsup_message m;
	struct e_link *e = msc_a->c.remote_to;

	if (!e) {
		LOG_MSC_A_REMOTE(msc_a, LOGL_ERROR, "No E link to remote MSC, cannot send AN-APDU\n");
		return -1;
	}

	if (e_prep_gsup_msg(e, &m)) {
		LOG_MSC_A_REMOTE(msc_a, LOGL_ERROR, "Error composing E-interface GSUP message\n");
		return -1;
	}
	m.message_type = message_type;
	if (an_apdu) {
		if (gsup_msg_assign_an_apdu(&m, an_apdu)) {
			LOG_MSC_A_REMOTE(msc_a, LOGL_ERROR, "Error composing E-interface GSUP message\n");
			return -1;
		}
	}

	return e_tx(e, &m);
}

/*     [MSC-A-----------------]            [MSC-B-----------------]
 *      msc_a --> msc_t_remote ----GSUP---> msc_a_remote --> msc_t ---BSSMAP--> [BSS]
 *                                        ^you are here
 */
static void msc_a_remote_rx_gsup_to_msc_t(struct msc_a *msc_a, const struct osmo_gsup_message *gsup_msg)
{
	uint32_t event;
	struct an_apdu an_apdu;

	switch (gsup_msg->message_type) {
	case OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST:
		event = MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST;
		break;

	case OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST:
	case OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST:
		event = MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST;
		break;

	case OSMO_GSUP_MSGT_E_CLOSE:
	case OSMO_GSUP_MSGT_E_ABORT:
	case OSMO_GSUP_MSGT_E_ROUTING_ERROR:
		/* TODO: maybe some non-"normal" release with error cause? */
		msc_a_release_cn(msc_a);
		return;

	default:
		LOG_MSC_A_REMOTE(msc_a, LOGL_ERROR, "Unhandled GSUP message type: %s\n",
				 osmo_gsup_message_type_name(gsup_msg->message_type));
		return;
	};

	gsup_msg_to_an_apdu(&an_apdu, gsup_msg);
	msub_role_dispatch(msc_a->c.msub, MSC_ROLE_T, event, &an_apdu);
	if (an_apdu.msg)
		msgb_free(an_apdu.msg);
}

/*     [MSC-A-----------------]            [MSC-B-----------------]
 *      msc_a --> msc_i_remote ----GSUP---> msc_a_remote --> msc_i ---BSSMAP--> [BSS]
 *                                        ^you are here
 */
static void msc_a_remote_rx_gsup_to_msc_i(struct msc_a *msc_a, const struct osmo_gsup_message *gsup_msg)
{
	uint32_t event;
	struct an_apdu an_apdu;

	switch (gsup_msg->message_type) {
	case OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST:
		event = MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST;
		break;

	case OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_ERROR:
	case OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_RESULT:
		event = MSC_I_EV_FROM_A_SEND_END_SIGNAL_RESPONSE;
		break;

	case OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT:
	case OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_ERROR:
		event = MSC_I_EV_FROM_A_PREPARE_SUBSEQUENT_HANDOVER_RESULT;
		break;

	case OSMO_GSUP_MSGT_E_CLOSE:
	case OSMO_GSUP_MSGT_E_ABORT:
	case OSMO_GSUP_MSGT_E_ROUTING_ERROR:
		/* TODO: maybe some non-"normal" release with error cause? */
		msc_a_release_cn(msc_a);
		return;

	default:
		LOG_MSC_A_REMOTE(msc_a, LOGL_ERROR, "Unhandled GSUP message type: %s\n",
				 osmo_gsup_message_type_name(gsup_msg->message_type));
		return;
	};

	gsup_msg_to_an_apdu(&an_apdu, gsup_msg);
	msub_role_dispatch(msc_a->c.msub, MSC_ROLE_I, event, &an_apdu);
	if (an_apdu.msg)
		msgb_free(an_apdu.msg);
}

static void msc_a_remote_send_handover_failure(struct msc_a *msc_a, enum gsm0808_cause cause)
{
	struct ran_msg ran_enc_msg = {
		.msg_type = RAN_MSG_HANDOVER_FAILURE,
		.handover_failure = {
			.cause = cause,
		},
	};
	struct an_apdu an_apdu = {
		.an_proto = msc_a->c.ran->an_proto,
		.msg = msc_role_ran_encode(msc_a->c.fi, &ran_enc_msg),
	};
	if (!an_apdu.msg)
		return;

	msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_T, OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_ERROR, &an_apdu);
	msgb_free(an_apdu.msg);
	return;
}

/*     [MSC-A---------------------]            [MSC-B---------------------]
 *      msc_a --> msc_{i,t}_remote ----GSUP---> msc_a_remote --> msc_{i,t} ---BSSMAP--> [BSS]
 *                                            ^you are here
 */
static void msc_a_remote_rx_gsup(struct msc_a *msc_a, const struct osmo_gsup_message *gsup_msg)
{
	struct msc_t *msc_t = msc_a_msc_t(msc_a);
	struct msc_i *msc_i = msc_a_msc_i(msc_a);

	/* If starting a new Handover, this subscriber *must* be new and completely unattached. Create a new msc_t role
	 * to receive below event. */
	if (gsup_msg->message_type == OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST) {
		if (msc_t || msc_i) {
			LOG_MSC_A_REMOTE_CAT(msc_a, DLGSUP, LOGL_ERROR,
					     "Already have an MSC-T or -I role, cannot Rx %s from remote MSC\n",
					     osmo_gsup_message_type_name(gsup_msg->message_type));
			msc_a_remote_send_handover_failure(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE);
			return;
		}

		msc_t = msc_t_alloc_without_ran_peer(msc_a->c.msub, msc_a->c.ran);
	}

	/* We are on a remote MSC-B. If an msub has an MSC-T role, this is the remote target of a handover, and all
	 * messages from MSC-A *must* be intended for the MSC-T role. As soon as the Handover is successful, the MSC-T
	 * role disappears and an MSC-I role appears. */
	if (msc_t) {
		LOG_MSC_A_REMOTE_CAT(msc_a, DLGSUP, LOGL_DEBUG, "Routing to MSC-T: %s\n",
				     osmo_gsup_message_type_name(gsup_msg->message_type));
		msc_a_remote_rx_gsup_to_msc_t(msc_a, gsup_msg);
	} else if (msc_i) {
		LOG_MSC_A_REMOTE_CAT(msc_a, DLGSUP, LOGL_DEBUG, "Routing to MSC-I: %s\n",
				     osmo_gsup_message_type_name(gsup_msg->message_type));
		msc_a_remote_rx_gsup_to_msc_i(msc_a, gsup_msg);
	} else {
		LOG_MSC_A_REMOTE_CAT(msc_a, DLGSUP, LOGL_ERROR,
				     "No MSC-T nor MSC-I role present, cannot Rx GSUP %s\n",
				     osmo_gsup_message_type_name(gsup_msg->message_type));
	}
}

static void msc_a_remote_fsm_communicating(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct msc_a *msc_a = msc_a_remote_priv(fi);
	struct an_apdu *an_apdu;

	switch (event) {

	case MSC_REMOTE_EV_RX_GSUP:
		/*     [MSC-A---------------------]            [MSC-B---------------------]
		 *      msc_a --> msc_{i,t}_remote ----GSUP---> msc_a_remote --> msc_{i,t} ---BSSMAP--> [BSS]
		 *                                            ^you are here
		 */
		msc_a_remote_rx_gsup(msc_a, (const struct osmo_gsup_message*)data);
		return;

	/* For all remaining cases:
	 *     [MSC-A---------------------]            [MSC-B---------------------]
	 *      msc_a <-- msc_{i,t}_remote <---GSUP---- msc_a_remote <-- msc_{i,t} <--BSSMAP--- [BSS]
	 *                                               you are here^
	 */

	case MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST:
		an_apdu = data;
		msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_I,
						  OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST, an_apdu);
		return;

	case MSC_A_EV_FROM_I_PREPARE_SUBSEQUENT_HANDOVER_REQUEST:
		an_apdu = data;
		msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_I,
						  OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST, an_apdu);
		return;

	case MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST:
		an_apdu = data;
		msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_I,
						  OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST, an_apdu);
		return;

	case MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE:
		an_apdu = data;
		msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_T,
						  OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_RESULT, an_apdu);
		return;

	case MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE:
		an_apdu = data;
		msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_T,
						  OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_ERROR, an_apdu);
		return;

	case MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST:
		an_apdu = data;
		msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_T,
						  OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST, an_apdu);
		return;

	case MSC_A_EV_FROM_T_SEND_END_SIGNAL_REQUEST:
		an_apdu = data;
		msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_T,
						  OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST, an_apdu);
		return;

	case MSC_A_EV_CN_CLOSE:
	case MSC_A_EV_MO_CLOSE:
		osmo_fsm_inst_state_chg(msc_a->c.fi, MSC_A_ST_RELEASING, 0, 0);
		return;

	default:
		OSMO_ASSERT(false);
	}
}

static void msc_a_remote_fsm_releasing_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, fi);
}

static void msc_a_remote_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
{
	struct msc_a *msc_a = msc_a_remote_priv(fi);
	if (msc_a->c.msub->role[MSC_ROLE_I])
		msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_I, OSMO_GSUP_MSGT_E_CLOSE, NULL);
	if (msc_a->c.msub->role[MSC_ROLE_T])
		msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_T, OSMO_GSUP_MSGT_E_CLOSE, NULL);
}

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

/* FSM events are by definition compatible with msc_a_fsm. States could be a separate enum, but so that
 * msc_a_is_accepted() also works on remote msc_a, this FSM shares state numbers with the msc_a_fsm_states. */
static const struct osmo_fsm_state msc_a_remote_fsm_states[] = {
	/* Whichever MSC_A_ST would be the first for the real MSC-A implementation, a fresh FSM instance will start in
	 * state == 0 and we just need to be able to transition out of it. */
	[0] = {
		.name = "INIT-REMOTE",
		.out_state_mask = 0
			| S(MSC_A_ST_COMMUNICATING)
			| S(MSC_A_ST_RELEASING)
			,
	},
	[MSC_A_ST_COMMUNICATING] = {
		.name = "COMMUNICATING",
		.action = msc_a_remote_fsm_communicating,
		.in_event_mask = 0
			| S(MSC_REMOTE_EV_RX_GSUP)
			| S(MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST)
			| S(MSC_A_EV_FROM_I_PREPARE_SUBSEQUENT_HANDOVER_REQUEST)
			| S(MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST)
			| S(MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE)
			| S(MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE)
			| S(MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST)
			| S(MSC_A_EV_FROM_T_SEND_END_SIGNAL_REQUEST)
			| S(MSC_A_EV_CN_CLOSE)
			| S(MSC_A_EV_MO_CLOSE)
			,
		.out_state_mask = 0
			| S(MSC_A_ST_RELEASING)
			,
	},
	[MSC_A_ST_RELEASING] = {
		.name = "RELEASING",
		.onenter = msc_a_remote_fsm_releasing_onenter,
	},
};

static struct osmo_fsm msc_a_remote_fsm = {
	.name = "msc_a_remote",
	.states = msc_a_remote_fsm_states,
	.num_states = ARRAY_SIZE(msc_a_remote_fsm_states),
	.log_subsys = DMSC,
	.event_names = msc_a_fsm_event_names,
	.cleanup = msc_a_remote_fsm_cleanup,
};

static __attribute__((constructor)) void msc_a_remote_fsm_init(void)
{
	OSMO_ASSERT(osmo_fsm_register(&msc_a_remote_fsm) == 0);
}

struct msc_a *msc_a_remote_alloc(struct msub *msub, struct ran_infra *ran,
				 const uint8_t *remote_msc_name, size_t remote_msc_name_len)
{
	struct msc_a *msc_a;

	msub_role_alloc(msub, MSC_ROLE_A, &msc_a_remote_fsm, struct msc_a, ran);
	msc_a = msub_msc_a(msub);
	if (!msc_a) {
		LOG_MSUB(msub, LOGL_ERROR, "Error setting up MSC-A remote role\n");
		return NULL;
	}

	msc_a->c.remote_to = e_link_alloc(msub_net(msub)->gcm, msc_a->c.fi, remote_msc_name, remote_msc_name_len);
	if (!msc_a->c.remote_to) {
		LOG_MSC_A_REMOTE(msc_a, LOGL_ERROR, "Failed to set up E link\n");
		msc_a_release_cn(msc_a);
		return NULL;
	}

	msc_a_update_id(msc_a);

	/* Immediately get out of state 0. */
	osmo_fsm_inst_state_chg(msc_a->c.fi, MSC_A_ST_COMMUNICATING, 0, 0);

	return msc_a;
}
