/*
 * (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 <osmocom/core/fsm.h>

#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>

#include <osmocom/msc/debug.h>
#include <osmocom/msc/transaction.h>
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/rtp_stream.h>

#define LOG_RTPS(rtps, level, fmt, args...) \
	LOGPFSML(rtps->fi, level, fmt, ##args)

enum rtp_stream_event {
	RTP_STREAM_EV_CRCX_OK,
	RTP_STREAM_EV_CRCX_FAIL,
	RTP_STREAM_EV_MDCX_OK,
	RTP_STREAM_EV_MDCX_FAIL,
};

enum rtp_stream_state {
	RTP_STREAM_ST_UNINITIALIZED,
	RTP_STREAM_ST_ESTABLISHING,
	RTP_STREAM_ST_ESTABLISHED,
	RTP_STREAM_ST_DISCARDING,
};

static struct osmo_fsm rtp_stream_fsm;

static struct osmo_tdef_state_timeout rtp_stream_fsm_timeouts[32] = {
	[RTP_STREAM_ST_ESTABLISHING] = { .T = -2 },
};

#define rtp_stream_state_chg(rtps, state) \
	osmo_tdef_fsm_inst_state_chg((rtps)->fi, state, rtp_stream_fsm_timeouts, g_mgw_tdefs, 5)

static __attribute__((constructor)) void rtp_stream_init()
{
	OSMO_ASSERT(osmo_fsm_register(&rtp_stream_fsm) == 0);
}

void rtp_stream_update_id(struct rtp_stream *rtps)
{
	char buf[256];
	char *p;
	struct osmo_strbuf sb = { .buf = buf, .len = sizeof(buf) };
	OSMO_STRBUF_PRINTF(sb, "%s", rtps->fi->proc.parent->id);
	if (rtps->for_trans)
		OSMO_STRBUF_PRINTF(sb, ":trans-%u", rtps->for_trans->transaction_id);
	OSMO_STRBUF_PRINTF(sb, ":call-%u", rtps->call_id);
	OSMO_STRBUF_PRINTF(sb, ":%s", rtp_direction_name(rtps->dir));
	if (!osmo_mgcpc_ep_ci_id(rtps->ci)) {
		OSMO_STRBUF_PRINTF(sb, ":no-CI");
	} else {
		OSMO_STRBUF_PRINTF(sb, ":CI-%s", osmo_mgcpc_ep_ci_id(rtps->ci));
		if (!osmo_sockaddr_str_is_nonzero(&rtps->remote))
			OSMO_STRBUF_PRINTF(sb, ":no-remote-port");
		else if (!rtps->remote_sent_to_mgw)
			OSMO_STRBUF_PRINTF(sb, ":remote-port-not-sent");
		if (!rtps->codec_known)
			OSMO_STRBUF_PRINTF(sb, ":no-codec");
		else if (!rtps->codec_sent_to_mgw)
			OSMO_STRBUF_PRINTF(sb, ":codec-not-sent");
		if (rtps->use_osmux) {
			if (rtps->remote_osmux_cid < 0)
				OSMO_STRBUF_PRINTF(sb, ":no-remote-osmux-cid");
			else if (!rtps->remote_osmux_cid_sent_to_mgw)
				OSMO_STRBUF_PRINTF(sb, ":remote-osmux-cid-not-sent");
		}
	}
	if (osmo_sockaddr_str_is_nonzero(&rtps->local))
		OSMO_STRBUF_PRINTF(sb, ":local-%s-%u", rtps->local.ip, rtps->local.port);
	if (osmo_sockaddr_str_is_nonzero(&rtps->remote))
		OSMO_STRBUF_PRINTF(sb, ":remote-%s-%u", rtps->remote.ip, rtps->remote.port);
	if (rtps->use_osmux)
		OSMO_STRBUF_PRINTF(sb, ":osmux-%d-%d", rtps->local_osmux_cid, rtps->remote_osmux_cid);

	/* Replace any dots in the IP address, dots not allowed as FSM instance name */
	for (p = buf; *p; p++)
		if (*p == '.')
			*p = '-';

	osmo_fsm_inst_update_id_f(rtps->fi, "%s", buf);
}

/* Allocate RTP stream under a call leg. This is one RTP connection from some remote entity with address and port to a
 * local RTP address and port. call_id is stored for sending in MGCP transactions and as logging context. for_trans is
 * optional, merely stored for reference by callers, and appears as log context if not NULL. */
struct rtp_stream *rtp_stream_alloc(struct call_leg *parent_call_leg, enum rtp_direction dir,
				    uint32_t call_id, struct gsm_trans *for_trans)
{
	struct osmo_fsm_inst *fi;
	struct rtp_stream *rtps;

	fi = osmo_fsm_inst_alloc_child(&rtp_stream_fsm, parent_call_leg->fi, CALL_LEG_EV_RTP_STREAM_GONE);
	OSMO_ASSERT(fi);

	rtps = talloc(fi, struct rtp_stream);
	OSMO_ASSERT(rtps);
	fi->priv = rtps;
	*rtps = (struct rtp_stream){
		.fi = fi,
		.parent_call_leg = parent_call_leg,
		.call_id = call_id,
		.for_trans = for_trans,
		.dir = dir,
		.local_osmux_cid = -2,
		.remote_osmux_cid = -2,
	};

	rtp_stream_update_id(rtps);

	return rtps;
}

static void check_established(struct rtp_stream *rtps)
{
	if (rtps->fi->state != RTP_STREAM_ST_ESTABLISHED
	    && osmo_sockaddr_str_is_nonzero(&rtps->local)
	    && osmo_sockaddr_str_is_nonzero(&rtps->remote)
	    && rtps->remote_sent_to_mgw
	    && (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw)
	    && rtps->codec_known)
		rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHED);
}

static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct rtp_stream *rtps = fi->priv;
	const struct mgcp_conn_peer *crcx_info;
	switch (event) {
	case RTP_STREAM_EV_CRCX_OK:
		crcx_info = osmo_mgcpc_ep_ci_get_rtp_info(rtps->ci);
		if (!crcx_info) {
			LOG_RTPS(rtps, LOGL_ERROR, "osmo_mgcpc_ep_ci_get_rtp_info() has "
				 "failed, ignoring %s\n", osmo_fsm_event_name(fi->fsm, event));
			return;
		}

		osmo_sockaddr_str_from_str(&rtps->local, crcx_info->addr, crcx_info->port);
		if (rtps->use_osmux != crcx_info->x_osmo_osmux_use) {
			LOG_RTPS(rtps, LOGL_ERROR, "Osmux usage request and response don't match: %d vs %d",
				 rtps->use_osmux, crcx_info->x_osmo_osmux_use);
			/* TODO: proper failure path */
			OSMO_ASSERT(rtps->use_osmux != crcx_info->x_osmo_osmux_use);
		}
		if (crcx_info->x_osmo_osmux_use)
			rtps->local_osmux_cid = crcx_info->x_osmo_osmux_cid;
		rtp_stream_update_id(rtps);
		osmo_fsm_inst_dispatch(fi->proc.parent, CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE, rtps);
		check_established(rtps);

		if ((!rtps->remote_sent_to_mgw || !rtps->codec_sent_to_mgw)
		    && osmo_sockaddr_str_is_nonzero(&rtps->remote)
		    && (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw)
		    && rtps->codec_known) {
			LOG_RTPS(rtps, LOGL_DEBUG,
				 "local ip:port set;%s%s%s triggering MDCX to send the new settings\n",
				 (!rtps->remote_sent_to_mgw)? " remote ip:port not yet sent," : "",
				 (!rtps->codec_sent_to_mgw)? " codec not yet sent," : "",
				 (rtps->use_osmux && !rtps->remote_osmux_cid_sent_to_mgw) ? "Osmux CID not yet sent,": "");
			rtp_stream_do_mdcx(rtps);
		}
		return;

	case RTP_STREAM_EV_MDCX_OK:
		rtp_stream_update_id(rtps);
		check_established(rtps);
		return;

	case RTP_STREAM_EV_CRCX_FAIL:
	case RTP_STREAM_EV_MDCX_FAIL:
		rtps->remote_sent_to_mgw = false;
		rtps->codec_sent_to_mgw = false;
		rtps->remote_osmux_cid_sent_to_mgw = false;
		rtp_stream_update_id(rtps);
		rtp_stream_state_chg(rtps, RTP_STREAM_ST_DISCARDING);
		return;

	default:
		OSMO_ASSERT(false);
	};
}

void rtp_stream_fsm_established_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct rtp_stream *rtps = fi->priv;
	osmo_fsm_inst_dispatch(fi->proc.parent, CALL_LEG_EV_RTP_STREAM_ESTABLISHED, rtps);
}

static int rtp_stream_fsm_timer_cb(struct osmo_fsm_inst *fi)
{
	struct rtp_stream *rtps = fi->priv;
	rtp_stream_state_chg(rtps, RTP_STREAM_ST_DISCARDING);
	return 0;
}

static void rtp_stream_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
{
	struct rtp_stream *rtps = fi->priv;
	if (rtps->ci) {
		osmo_mgcpc_ep_cancel_notify(osmo_mgcpc_ep_ci_ep(rtps->ci), fi);
		osmo_mgcpc_ep_ci_dlcx(rtps->ci);
		rtps->ci = NULL;
	}
}

void rtp_stream_fsm_discarding_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL);
}

static const struct value_string rtp_stream_fsm_event_names[] = {
	OSMO_VALUE_STRING(RTP_STREAM_EV_CRCX_OK),
	OSMO_VALUE_STRING(RTP_STREAM_EV_CRCX_FAIL),
	OSMO_VALUE_STRING(RTP_STREAM_EV_MDCX_OK),
	OSMO_VALUE_STRING(RTP_STREAM_EV_MDCX_FAIL),
	{}
};

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

static const struct osmo_fsm_state rtp_stream_fsm_states[] = {
	[RTP_STREAM_ST_UNINITIALIZED] = {
		.name = "UNINITIALIZED",
		.out_state_mask = 0
			| S(RTP_STREAM_ST_ESTABLISHING)
			| S(RTP_STREAM_ST_DISCARDING)
			,
	},
	[RTP_STREAM_ST_ESTABLISHING] = {
		.name = "ESTABLISHING",
		.in_event_mask = 0
			| S(RTP_STREAM_EV_CRCX_OK)
			| S(RTP_STREAM_EV_CRCX_FAIL)
			| S(RTP_STREAM_EV_MDCX_OK)
			| S(RTP_STREAM_EV_MDCX_FAIL)
			,
		.out_state_mask = 0
			| S(RTP_STREAM_ST_ESTABLISHED)
			| S(RTP_STREAM_ST_DISCARDING)
			,
		.action = rtp_stream_fsm_establishing_established,
	},
	[RTP_STREAM_ST_ESTABLISHED] = {
		.name = "ESTABLISHED",
		.out_state_mask = 0
			| S(RTP_STREAM_ST_ESTABLISHING)
			| S(RTP_STREAM_ST_DISCARDING)
			,
		.onenter = rtp_stream_fsm_established_onenter,
		.action = rtp_stream_fsm_establishing_established,
	},
	[RTP_STREAM_ST_DISCARDING] = {
		.name = "DISCARDING",
		.onenter = rtp_stream_fsm_discarding_onenter,
		.out_state_mask = 0
			| S(RTP_STREAM_ST_DISCARDING)
			,
	},
};

static struct osmo_fsm rtp_stream_fsm = {
	.name = "rtp_stream",
	.states = rtp_stream_fsm_states,
	.num_states = ARRAY_SIZE(rtp_stream_fsm_states),
	.log_subsys = DCC,
	.event_names = rtp_stream_fsm_event_names,
	.timer_cb = rtp_stream_fsm_timer_cb,
	.cleanup = rtp_stream_fsm_cleanup,
};

static int rtp_stream_do_mgcp_verb(struct rtp_stream *rtps, enum mgcp_verb verb, uint32_t ok_event, uint32_t fail_event)
{
	struct mgcp_conn_peer verb_info;

	if (!rtps->ci) {
		LOG_RTPS(rtps, LOGL_ERROR, "Cannot send %s, no endpoint CI allocated\n", osmo_mgcp_verb_name(verb));
		return -EINVAL;
	}

	verb_info = (struct mgcp_conn_peer){
		.call_id = rtps->call_id,
		.ptime = 20,
		.x_osmo_osmux_use = rtps->use_osmux,
		.x_osmo_osmux_cid = rtps->remote_osmux_cid,
	};

	if (verb == MGCP_VERB_CRCX)
		verb_info.conn_mode = rtps->crcx_conn_mode;

	if (rtps->codec_known) {
		verb_info.codecs[0] = rtps->codec;
		verb_info.codecs_len = 1;
		rtps->codec_sent_to_mgw = true;
	}
	if (osmo_sockaddr_str_is_nonzero(&rtps->remote)) {
		int rc = osmo_strlcpy(verb_info.addr, rtps->remote.ip, sizeof(verb_info.addr));
		if (rc <= 0 || rc >= sizeof(verb_info.addr)) {
			LOG_RTPS(rtps, LOGL_ERROR, "Failure to write IP address to MGCP message (rc=%d)\n", rc);
			return -ENOSPC;
		}
		verb_info.port = rtps->remote.port;
		rtps->remote_sent_to_mgw = true;
	}

	osmo_mgcpc_ep_ci_request(rtps->ci, verb, &verb_info, rtps->fi, ok_event, fail_event, NULL);
	return 0;
}

int rtp_stream_ensure_ci(struct rtp_stream *rtps, struct osmo_mgcpc_ep *at_endpoint)
{
	if (rtps->ci)
		return rtp_stream_commit(rtps);

	rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING);

	rtps->ci = osmo_mgcpc_ep_ci_add(at_endpoint, "%s", rtp_direction_name(rtps->dir));
	if (!rtps->ci)
		return -ENODEV;

	return rtp_stream_do_mgcp_verb(rtps, MGCP_VERB_CRCX, RTP_STREAM_EV_CRCX_OK, RTP_STREAM_EV_CRCX_FAIL);
}

int rtp_stream_do_mdcx(struct rtp_stream *rtps)
{
	return rtp_stream_do_mgcp_verb(rtps, MGCP_VERB_MDCX, RTP_STREAM_EV_MDCX_OK, RTP_STREAM_EV_MDCX_FAIL);
}

void rtp_stream_release(struct rtp_stream *rtps)
{
	if (!rtps)
		return;

	rtp_stream_state_chg(rtps, RTP_STREAM_ST_DISCARDING);
}

/* After setting up a remote RTP address or a new codec, call this to trigger an MDCX.
 * The MDCX will only trigger if all data needed by an endpoint is available (both RTP address and codec) and if at
 * least one of them has not yet been sent to the MGW in a previous CRCX or MDCX. */
int rtp_stream_commit(struct rtp_stream *rtps)
{
	if (!rtps->ci) {
		LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no MGW endpoint CI set up\n");
		return -1;
	}
	if (!osmo_sockaddr_str_is_nonzero(&rtps->remote)) {
		LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no remote RTP address known\n");
		return -1;
	}
	if (!rtps->codec_known) {
		LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no codec known\n");
		return -1;
	}
	if (rtps->remote_sent_to_mgw && rtps->codec_sent_to_mgw) {
		LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: both remote RTP address and codec already set up at MGW\n");
		return 0;
	}

	LOG_RTPS(rtps, LOGL_DEBUG, "Committing: Tx MDCX to update the MGW: updating%s%s%s\n",
		 rtps->remote_sent_to_mgw ? "" : " remote-RTP-IP-port",
		 rtps->codec_sent_to_mgw ? "" : " codec",
		 (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw) ? "" : " remote-Osmux-CID");
	return rtp_stream_do_mdcx(rtps);
}

void rtp_stream_set_codec(struct rtp_stream *rtps, enum mgcp_codecs codec)
{
	if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED)
		rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING);
	LOG_RTPS(rtps, LOGL_DEBUG, "setting codec to %s\n", osmo_mgcpc_codec_name(codec));
	rtps->codec = codec;
	rtps->codec_known = true;
	rtps->codec_sent_to_mgw = false;
	rtp_stream_update_id(rtps);
}

void rtp_stream_set_remote_addr(struct rtp_stream *rtps, const struct osmo_sockaddr_str *r)
{
	if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED)
		rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING);
	LOG_RTPS(rtps, LOGL_DEBUG, "setting remote addr to " OSMO_SOCKADDR_STR_FMT "\n", OSMO_SOCKADDR_STR_FMT_ARGS(r));
	rtps->remote = *r;
	rtps->remote_sent_to_mgw = false;
	rtp_stream_update_id(rtps);
}

void rtp_stream_set_remote_osmux_cid(struct rtp_stream *rtps, uint8_t osmux_cid)
{
	if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED)
		rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING);
	LOG_RTPS(rtps, LOGL_DEBUG, "setting remote Osmux CID to %u\n", osmux_cid);
	rtps->remote_osmux_cid = osmux_cid;
	rtps->remote_osmux_cid_sent_to_mgw = false;
	rtp_stream_update_id(rtps);
}

bool rtp_stream_is_established(struct rtp_stream *rtps)
{
	if (!rtps)
		return false;
	if (!rtps->fi)
		return false;
	if (rtps->fi->state != RTP_STREAM_ST_ESTABLISHED)
		return false;
	if (!rtps->remote_sent_to_mgw
	    || !rtps->codec_sent_to_mgw
	    || (rtps->use_osmux && !rtps->remote_osmux_cid_sent_to_mgw))
		return false;
	return true;
}
