/* Routines for translation between codec representations: SDP, CC/BSSMAP variants, MGCP, MNCC */
/*
 * (C) 2019-2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * Author: Neels Hofmeyr
 *
 * SPDX-License-Identifier: AGPL-3.0+
 *
 * 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 <string.h>

#include <osmocom/gsm/mncc.h>

#include <osmocom/msc/sdp_msg.h>
#include <osmocom/msc/codec_mapping.h>
#include <osmocom/msc/mncc.h>

const struct codec_mapping codec_map[] = {
	/* FIXME: sdp.fmtp handling is not done properly yet, proper mode-set and octet-align handling will follow in
	 * separate patches. */
	{
		.sdp = {
			.payload_type = 0,
			.subtype_name = "PCMU",
			.rate = 8000,
		},
		.mgcp = CODEC_PCMU_8000_1,
	},
	{
		.sdp = {
			.payload_type = 3,
			.subtype_name = "GSM",
			.rate = 8000,
		},
		.mgcp = CODEC_GSM_8000_1,
		.speech_ver_count = 1,
		.speech_ver = { GSM48_BCAP_SV_FR },
		.mncc_payload_msg_type = GSM_TCHF_FRAME,
		.has_gsm0808_speech_codec = true,
		.gsm0808_speech_codec = {
			.fi = true,
			.type = GSM0808_SCT_FR1,
		},
		.perm_speech = GSM0808_PERM_FR1,
		.frhr = CODEC_FRHR_FR,
	},
	{
		.sdp = {
			.payload_type = 8,
			.subtype_name = "PCMA",
			.rate = 8000,
		},
		.mgcp = CODEC_PCMA_8000_1,
	},
	{
		.sdp = {
			.payload_type = 18,
			.subtype_name = "G729",
			.rate = 8000,
		},
		.mgcp = CODEC_G729_8000_1,
	},
	{
		.sdp = {
			.payload_type = 110,
			.subtype_name = "GSM-EFR",
			.rate = 8000,
		},
		.mgcp = CODEC_GSMEFR_8000_1,
		.speech_ver_count = 1,
		.speech_ver = { GSM48_BCAP_SV_EFR },
		.mncc_payload_msg_type = GSM_TCHF_FRAME_EFR,
		.has_gsm0808_speech_codec = true,
		.gsm0808_speech_codec = {
			.fi = true,
			.type = GSM0808_SCT_FR2,
		},
		.perm_speech = GSM0808_PERM_FR2,
		.frhr = CODEC_FRHR_FR,
	},
	{
		.sdp = {
			.payload_type = 111,
			.subtype_name = "GSM-HR-08",
			.rate = 8000,
		},
		.mgcp = CODEC_GSMHR_8000_1,
		.speech_ver_count = 1,
		.speech_ver = { GSM48_BCAP_SV_HR },
		.mncc_payload_msg_type = GSM_TCHH_FRAME,
		.has_gsm0808_speech_codec = true,
		.gsm0808_speech_codec = {
			.fi = true,
			.type = GSM0808_SCT_HR1,
		},
		.perm_speech = GSM0808_PERM_HR1,
		.frhr = CODEC_FRHR_HR,
	},
	{
		.sdp = {
			/* 112 is just what we use by default. The other call leg may impose a different number. */
			.payload_type = 112,
			.subtype_name = "AMR",
			.rate = 8000,
			/* AMR is always octet-aligned in 2G and 3G RAN, so this fmtp is signalled to remote call legs.
			 * So far, fmtp is ignored in incoming SIP SDP, so an incoming SDP without 'octet-align=1' will
			 * match with this entry; we will still reply with 'octet-align=1', which often works out. */
			.fmtp = "octet-align=1",
		},
		.mgcp = CODEC_AMR_8000_1,
		.speech_ver_count = 1,
		.speech_ver = { GSM48_BCAP_SV_AMR_F },
		.mncc_payload_msg_type = GSM_TCH_FRAME_AMR,
		.has_gsm0808_speech_codec = true,
		.gsm0808_speech_codec = {
			.fi = true,
			.type = GSM0808_SCT_FR3,
			.cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR,
		},
		.perm_speech = GSM0808_PERM_FR3,
		.frhr = CODEC_FRHR_FR,
	},
	{
		/* Another entry like the above, to map HR3 to AMR, too. */
		.sdp = {
			.payload_type = 112,
			.subtype_name = "AMR",
			.rate = 8000,
			.fmtp = "octet-align=1",
		},
		.mgcp = CODEC_AMR_8000_1,
		.speech_ver_count = 2,
		.speech_ver = { GSM48_BCAP_SV_AMR_H, GSM48_BCAP_SV_AMR_OH },
		.mncc_payload_msg_type = GSM_TCH_FRAME_AMR,
		.has_gsm0808_speech_codec = true,
		.gsm0808_speech_codec = {
			.fi = true,
			.type = GSM0808_SCT_HR3,
			.cfg = GSM0808_SC_CFG_DEFAULT_HR_AMR,
		},
		.perm_speech = GSM0808_PERM_HR3,
		.frhr = CODEC_FRHR_HR,
	},
	{
		.sdp = {
			.payload_type = 113,
			.subtype_name = "AMR-WB",
			.rate = 16000,
			.fmtp = "octet-align=1",
		},
		.mgcp = CODEC_AMRWB_16000_1,
		.speech_ver_count = 2,
		.speech_ver = { GSM48_BCAP_SV_AMR_OFW, GSM48_BCAP_SV_AMR_FW },
		.mncc_payload_msg_type = GSM_TCH_FRAME_AMR,
		.has_gsm0808_speech_codec = true,
		.gsm0808_speech_codec = {
			.fi = true,
			.type = GSM0808_SCT_FR5,
			.cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR_WB,
		},
		.perm_speech = GSM0808_PERM_FR5,
		.frhr = CODEC_FRHR_FR,
	},
	{
		/* Another entry like the above, to map HR4 to AMR-WB, too. */
		.sdp = {
			.payload_type = 113,
			.subtype_name = "AMR-WB",
			.rate = 16000,
			.fmtp = "octet-align=1",
		},
		.mgcp = CODEC_AMRWB_16000_1,
		.speech_ver_count = 1,
		.speech_ver = { GSM48_BCAP_SV_AMR_OHW },
		.mncc_payload_msg_type = GSM_TCH_FRAME_AMR,
		.has_gsm0808_speech_codec = true,
		.gsm0808_speech_codec = {
			.fi = true,
			.type = GSM0808_SCT_HR4,
			.cfg = GSM0808_SC_CFG_DEFAULT_OHR_AMR_WB,
		},
		.perm_speech = GSM0808_PERM_HR4,
		.frhr = CODEC_FRHR_HR,
	},
	{
		.sdp = {
			.payload_type = 96,
			.subtype_name = "VND.3GPP.IUFP",
			.rate = 16000,
		},
		.mgcp = CODEC_IUFP,
	},
	{
		.sdp = {
			.payload_type = 120,
			.subtype_name = "CLEARMODE",
			.rate = 8000,
		},
		.has_gsm0808_speech_codec = true,
		.gsm0808_speech_codec = {
			.pi = true, /* PI indicates CSDoIP is supported */
			.pt = false, /* PT indicates CSDoTDM is not supported */
			.type = GSM0808_SCT_CSD,
			.cfg = 0, /* R2/R3 not set (redundancy not supported) */
		},
		.mgcp = CODEC_CLEARMODE,
	},
};

#define foreach_codec_mapping(CODEC_MAPPING) \
	for ((CODEC_MAPPING) = codec_map; (CODEC_MAPPING) < codec_map + ARRAY_SIZE(codec_map); (CODEC_MAPPING)++)

const struct gsm_mncc_bearer_cap bearer_cap_empty = {
		.speech_ver = { -1 },
	};

const struct codec_mapping *codec_mapping_by_speech_ver(enum gsm48_bcap_speech_ver speech_ver)
{
	const struct codec_mapping *m;
	foreach_codec_mapping(m) {
		int i;
		for (i = 0; i < m->speech_ver_count; i++)
			if (m->speech_ver[i] == speech_ver)
				return m;
	}
	return NULL;
}

const struct codec_mapping *codec_mapping_by_gsm0808_speech_codec_type(enum gsm0808_speech_codec_type sct)
{
	const struct codec_mapping *m;
	foreach_codec_mapping(m) {
		if (!m->has_gsm0808_speech_codec)
			continue;
		if (m->gsm0808_speech_codec.type == sct)
			return m;
	}
	return NULL;
}

const struct codec_mapping *codec_mapping_by_gsm0808_speech_codec(const struct gsm0808_speech_codec *sc)
{
	const struct codec_mapping *m;
	foreach_codec_mapping(m) {
		if (!m->has_gsm0808_speech_codec)
			continue;
		if (m->gsm0808_speech_codec.type != sc->type)
			continue;
		/* Return only those where sc->cfg is a subset of m->gsm0808_speech_codec.cfg. */
		if ((m->gsm0808_speech_codec.cfg & sc->cfg) != sc->cfg)
			continue;
		return m;
	}
	return NULL;
}

const struct codec_mapping *codec_mapping_by_perm_speech(enum gsm0808_permitted_speech perm_speech)
{
	const struct codec_mapping *m;
	foreach_codec_mapping(m) {
		if (m->perm_speech == perm_speech)
			return m;
	}
	return NULL;
}

const struct codec_mapping *codec_mapping_by_subtype_name(const char *subtype_name)
{
	const struct codec_mapping *m;
	foreach_codec_mapping(m) {
		if (!strcmp(m->sdp.subtype_name, subtype_name))
			return m;
	}
	return NULL;
}

const struct codec_mapping *codec_mapping_by_mgcp_codec(enum mgcp_codecs mgcp)
{
	const struct codec_mapping *m;
	foreach_codec_mapping(m) {
		if (m->mgcp == mgcp)
			return m;
	}
	return NULL;
}

/* Append given Speech Version to the end of the Bearer Capabilities Speech Version array. Return 1 if added, zero
 * otherwise (as in, return the number of items added). */
int bearer_cap_add_speech_ver(struct gsm_mncc_bearer_cap *bearer_cap, enum gsm48_bcap_speech_ver speech_ver)
{
	int i;
	for (i = 0; i < ARRAY_SIZE(bearer_cap->speech_ver) - 1; i++) {
		if (bearer_cap->speech_ver[i] == speech_ver)
			return 0;
		if (bearer_cap->speech_ver[i] == -1) {
			bearer_cap->speech_ver[i] = speech_ver;
			bearer_cap->speech_ver[i+1] = -1;
			return 1;
		}
	}
	return 0;
}

/* From the current speech_ver list present in the bearer_cap, set the bearer_cap.radio.
 * If a HR speech_ver is present, set to GSM48_BCAP_RRQ_DUAL_FR, otherwise set to GSM48_BCAP_RRQ_FR_ONLY. */
int bearer_cap_set_radio(struct gsm_mncc_bearer_cap *bearer_cap)
{
	bool hr_present = false;
	int i;
	for (i = 0; i < ARRAY_SIZE(bearer_cap->speech_ver) - 1; i++) {
		const struct codec_mapping *m;

		if (bearer_cap->speech_ver[i] == -1)
			break;

		m = codec_mapping_by_speech_ver(bearer_cap->speech_ver[i]);

		if (!m)
			continue;

		if (m->frhr == CODEC_FRHR_HR)
			hr_present = true;
	}

	if (hr_present)
		bearer_cap->radio = GSM48_BCAP_RRQ_DUAL_FR;
	else
		bearer_cap->radio = GSM48_BCAP_RRQ_FR_ONLY;

	return 0;
}

/* Try to convert the SDP audio codec name to Speech Versions to append to Bearer Capabilities.
 * Return the number of Speech Version entries added (some may add more than one, others may be unknown/unapplicable and
 * return 0). */
int sdp_audio_codec_add_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codec *codec)
{
	const struct codec_mapping *m;
	int added = 0;
	foreach_codec_mapping(m) {
		int i;
		if (strcmp(m->sdp.subtype_name, codec->subtype_name))
			continue;
		/* TODO also match rate and fmtp? */
		for (i = 0; i < m->speech_ver_count; i++)
			added += bearer_cap_add_speech_ver(bearer_cap, m->speech_ver[i]);
	}
	return added;
}

/* Append all audio codecs found in given sdp_msg to Bearer Capability, by traversing all codec entries with
 * sdp_audio_codec_add_to_bearer_cap(). Return the number of Speech Version entries added.
 * Note that Speech Version entries are only appended, no previous entries are removed.
 * Note that only the Speech Version entries are modified; to make a valid Bearer Capabiliy, at least bearer_cap->radio
 * must also be set (before or after this function); see also bearer_cap_set_radio(). */
int sdp_audio_codecs_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codecs *ac)
{
	const struct sdp_audio_codec *codec;
	int added = 0;

	sdp_audio_codecs_foreach(codec, ac) {
		added += sdp_audio_codec_add_to_bearer_cap(bearer_cap, codec);
	}

	return added;
}

/* Convert Speech Version to SDP audio codec and append to SDP message struct. */
struct sdp_audio_codec *sdp_audio_codecs_add_speech_ver(struct sdp_audio_codecs *ac,
							enum gsm48_bcap_speech_ver speech_ver)
{
	const struct codec_mapping *m;
	struct sdp_audio_codec *ret = NULL;
	foreach_codec_mapping(m) {
		int i;
		for (i = 0; i < m->speech_ver_count; i++) {
			if (m->speech_ver[i] == speech_ver) {
				ret = sdp_audio_codecs_add_copy(ac, &m->sdp);
				break;
			}
		}
	}
	return ret;
}

struct sdp_audio_codec *sdp_audio_codecs_add_mgcp_codec(struct sdp_audio_codecs *ac, enum mgcp_codecs mgcp_codec)
{
	const struct codec_mapping *m = codec_mapping_by_mgcp_codec(mgcp_codec);
	if (!m)
		return NULL;
	return sdp_audio_codecs_add_copy(ac, &m->sdp);
}

void sdp_audio_codecs_from_bearer_cap(struct sdp_audio_codecs *ac, const struct gsm_mncc_bearer_cap *bc)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(bc->speech_ver); i++) {
		if (bc->speech_ver[i] == -1)
			break;
		sdp_audio_codecs_add_speech_ver(ac, bc->speech_ver[i]);
	}
}

/* Append an entry for the given sdp_audio_codec to the gsm0808_speech_codec_list.
 * Return 0 if an entry was added, -ENOENT when there is no mapping to gsm0808_speech_codec for the given
 * sdp_audio_codec, and -ENOSPC when scl is full and nothing could be added. */
int sdp_audio_codec_to_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct sdp_audio_codec *codec)
{
	const struct codec_mapping *m = codec_mapping_by_subtype_name(codec->subtype_name);
	if (!m)
		return -ENOENT;
	if (!m->has_gsm0808_speech_codec)
		return -ENOENT;
	if (scl->len >= ARRAY_SIZE(scl->codec))
		return -ENOSPC;
	scl->codec[scl->len] = m->gsm0808_speech_codec;
	/* FIXME: apply AMR configuration according to codec->fmtp */
	scl->len++;
	return 0;
}

void sdp_audio_codecs_to_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct sdp_audio_codecs *ac)
{
	const struct sdp_audio_codec *codec;

	*scl = (struct gsm0808_speech_codec_list){};

	sdp_audio_codecs_foreach(codec, ac) {
		int rc = sdp_audio_codec_to_speech_codec_list(scl, codec);
		if (rc == -ENOSPC)
			break;
	}
}

void sdp_audio_codecs_from_speech_codec_list(struct sdp_audio_codecs *ac, const struct gsm0808_speech_codec_list *cl)
{
	int i;
	for (i = 0; i < cl->len; i++) {
		const struct gsm0808_speech_codec *sc = &cl->codec[i];
		const struct codec_mapping *m = codec_mapping_by_gsm0808_speech_codec(sc);
		if (!m)
			continue;
		sdp_audio_codecs_add_copy(ac, &m->sdp);
		/* FIXME: for AMR, apply sc->cfg to the added codec's fmtp */
	}
}

int sdp_audio_codecs_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct sdp_audio_codecs *ac)
{
	const struct sdp_audio_codec *codec;
	bool fr_present = false;
	int first_fr_idx = -1;
	bool hr_present = false;
	int first_hr_idx = -1;
	int idx = -1;

	*ct = (struct gsm0808_channel_type){
		.ch_indctr = GSM0808_CHAN_SPEECH,
	};

	sdp_audio_codecs_foreach(codec, ac) {
		const struct codec_mapping *m;
		int i;
		bool dup;
		idx++;
		foreach_codec_mapping(m) {
			if (strcmp(m->sdp.subtype_name, codec->subtype_name))
				continue;

			switch (m->perm_speech) {
			default:
				continue;

			case GSM0808_PERM_FR1:
			case GSM0808_PERM_FR2:
			case GSM0808_PERM_FR3:
			case GSM0808_PERM_FR4:
			case GSM0808_PERM_FR5:
				fr_present = true;
				if (first_fr_idx < 0)
					first_fr_idx = idx;
				break;

			case GSM0808_PERM_HR1:
			case GSM0808_PERM_HR2:
			case GSM0808_PERM_HR3:
			case GSM0808_PERM_HR4:
			case GSM0808_PERM_HR6:
				hr_present = true;
				if (first_hr_idx < 0)
					first_hr_idx = idx;
				break;
			}

			/* Avoid duplicates */
			dup = false;
			for (i = 0; i < ct->perm_spch_len; i++) {
				if (ct->perm_spch[i] == m->perm_speech) {
					dup = true;
					break;
				}
			}
			if (dup)
				continue;

			ct->perm_spch[ct->perm_spch_len] = m->perm_speech;
			ct->perm_spch_len++;
		}
	}

	if (fr_present && hr_present) {
		if (first_fr_idx <= first_hr_idx)
			ct->ch_rate_type = GSM0808_SPEECH_FULL_PREF;
		else
			ct->ch_rate_type = GSM0808_SPEECH_HALF_PREF;
	} else if (fr_present && !hr_present)
		ct->ch_rate_type = GSM0808_SPEECH_FULL_BM;
	else if (!fr_present && hr_present)
		ct->ch_rate_type = GSM0808_SPEECH_HALF_LM;
	else
		return -EINVAL;
	return 0;
}

enum mgcp_codecs sdp_audio_codec_to_mgcp_codec(const struct sdp_audio_codec *codec)
{
	const struct codec_mapping *m;
	foreach_codec_mapping(m) {
		if (!sdp_audio_codec_cmp(&m->sdp, codec, false, false))
			return m->mgcp;
	}
	return NO_MGCP_CODEC;
}
