/* 3GPP TS 122.002 Bearer Services */
/*
 * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * Author: Oliver Smith
 *
 * 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 <errno.h>

#include <osmocom/msc/csd_bs.h>
#include <osmocom/msc/debug.h>

/* csd_bs related below */

struct csd_bs_map {
	/* BS number (20, 21, ...) */
	unsigned int num;
	/* Access Structure (1: asynchronous, 0: synchronous) */
	bool async;
	/* QoS Attribute (1: transparent, 0: non-transparent) */
	bool transp;
	/* Rate Adaption (V110, V120 etc.) */
	enum gsm48_bcap_ra ra;
	/* Fixed Network User Rate */
	unsigned int rate;
};

static const struct csd_bs_map bs_map[] = {
	/* 3.1.1.1.2 */
	[CSD_BS_21_T_V110_0k3] = {
		.num = 21,
		.async = true,
		.transp = true,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 300,
	},
	[CSD_BS_22_T_V110_1k2] = {
		.num = 22,
		.async = true,
		.transp = true,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 1200,
	},
	[CSD_BS_24_T_V110_2k4] = {
		.num = 24,
		.async = true,
		.transp = true,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 2400,
	},
	[CSD_BS_25_T_V110_4k8] = {
		.num = 25,
		.async = true,
		.transp = true,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 4800,
	},
	[CSD_BS_26_T_V110_9k6] = {
		.num = 26,
		.async = true,
		.transp = true,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 9600,
	},

	/* 3.1.1.2.2 */
	[CSD_BS_21_NT_V110_0k3] = {
		.num = 21,
		.async = true,
		.transp = false,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 300,
	},
	[CSD_BS_22_NT_V110_1k2] = {
		.num = 22,
		.async = true,
		.transp = false,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 1200,
	},
	[CSD_BS_24_NT_V110_2k4] = {
		.num = 24,
		.async = true,
		.transp = false,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 2400,
	},
	[CSD_BS_25_NT_V110_4k8] = {
		.num = 25,
		.async = true,
		.transp = false,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 4800,
	},
	[CSD_BS_26_NT_V110_9k6] = {
		.num = 26,
		.async = true,
		.transp = false,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 9600,
	},

	/* 3.1.2.1.2 */
	[CSD_BS_31_T_V110_1k2] = {
		.num = 31,
		.async = false,
		.transp = true,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 1200,
	},
	[CSD_BS_32_T_V110_2k4] = {
		.num = 32,
		.async = false,
		.transp = true,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 2400,
	},
	[CSD_BS_33_T_V110_4k8] = {
		.num = 33,
		.async = false,
		.transp = true,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 4800,
	},
	[CSD_BS_34_T_V110_9k6] = {
		.num = 34,
		.async = false,
		.transp = true,
		.ra = GSM48_BCAP_RA_V110_X30,
		.rate = 9600,
	},
};

osmo_static_assert(ARRAY_SIZE(bs_map) == CSD_BS_MAX, _invalid_size_bs_map);

bool csd_bs_is_transp(enum csd_bs bs)
{
	return bs_map[bs].transp;
}

/* Short single-line representation, convenient for logging.
 * Like "BS25NT" */
int csd_bs_to_str_buf(char *buf, size_t buflen, enum csd_bs bs)
{
	struct osmo_strbuf sb = { .buf = buf, .len = buflen };
	const struct csd_bs_map *map = &bs_map[bs];

	OSMO_STRBUF_PRINTF(sb, "BS%u%s",
			   map->num,
			   map->transp ? "T" : "NT");

	if (map->ra != GSM48_BCAP_RA_V110_X30)
		OSMO_STRBUF_PRINTF(sb, "-RA=%d", map->ra);

	return sb.chars_needed;
}

char *csd_bs_to_str_c(void *ctx, enum csd_bs bs)
{
	OSMO_NAME_C_IMPL(ctx, 32, "csd_bs_to_str_c-ERROR", csd_bs_to_str_buf, bs)
}

const char *csd_bs_to_str(enum csd_bs bs)
{
	return csd_bs_to_str_c(OTC_SELECT, bs);
}

static int csd_bs_to_gsm0808_data_rate_transp(enum csd_bs bs, uint8_t *ch_rate_type)
{
	switch (bs_map[bs].rate) {
	case 300:
		*ch_rate_type = GSM0808_DATA_FULL_PREF;
		return GSM0808_DATA_RATE_TRANSP_600;
	case 1200:
		*ch_rate_type = GSM0808_DATA_FULL_PREF;
		return GSM0808_DATA_RATE_TRANSP_1k2;
	case 2400:
		*ch_rate_type = GSM0808_DATA_FULL_PREF;
		return GSM0808_DATA_RATE_TRANSP_2k4;
	case 4800:
		*ch_rate_type = GSM0808_DATA_FULL_PREF;
		return GSM0808_DATA_RATE_TRANSP_4k8;
	case 9600:
		*ch_rate_type = GSM0808_DATA_FULL_BM;
		return GSM0808_DATA_RATE_TRANSP_9k6;
	}
	return -EINVAL;
}

static int csd_bs_to_gsm0808_data_rate_non_transp(enum csd_bs bs, uint8_t *ch_rate_type)
{
	uint16_t rate = bs_map[bs].rate;

	if (rate < 6000) {
		*ch_rate_type = GSM0808_DATA_FULL_PREF;
		return GSM0808_DATA_RATE_NON_TRANSP_6k0;
	}
	if (rate < 12000) {
		*ch_rate_type = GSM0808_DATA_FULL_BM;
		return GSM0808_DATA_RATE_NON_TRANSP_12k0;
	}

	return -EINVAL;
}

static int csd_bs_to_gsm0808_data_rate_non_transp_allowed(enum csd_bs bs)
{
	uint16_t rate = bs_map[bs].rate;

	if (rate < 6000)
		return GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_6k0;
	if (rate < 12000)
		return GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_12k0;

	return -EINVAL;
}

enum csd_bs csd_bs_from_bearer_cap(const struct gsm_mncc_bearer_cap *cap, bool transp)
{
	enum gsm48_bcap_ra ra = cap->data.rate_adaption;
	enum gsm48_bcap_user_rate rate = cap->data.user_rate;
	bool async = cap->data.async;

	/* 3.1kHz CSD calls won't have the rate adaptation field set
	   but do require rate adaptation. */
	if (cap->data.interm_rate && !ra)
		ra = GSM48_BCAP_RA_V110_X30;

	if (ra == GSM48_BCAP_RA_V110_X30 && async && transp) {
		switch (rate) {
		case GSM48_BCAP_UR_300:
			return CSD_BS_21_T_V110_0k3;
		case GSM48_BCAP_UR_1200:
			return CSD_BS_22_T_V110_1k2;
		case GSM48_BCAP_UR_2400:
			return CSD_BS_24_T_V110_2k4;
		case GSM48_BCAP_UR_4800:
			return CSD_BS_25_T_V110_4k8;
		case GSM48_BCAP_UR_9600:
			return CSD_BS_26_T_V110_9k6;
		default:
			return CSD_BS_NONE;
		}
	}

	if (ra == GSM48_BCAP_RA_V110_X30 && async && !transp) {
		switch (rate) {
		case GSM48_BCAP_UR_300:
			return CSD_BS_21_NT_V110_0k3;
		case GSM48_BCAP_UR_1200:
			return CSD_BS_22_NT_V110_1k2;
		case GSM48_BCAP_UR_2400:
			return CSD_BS_24_NT_V110_2k4;
		case GSM48_BCAP_UR_4800:
			return CSD_BS_25_NT_V110_4k8;
		case GSM48_BCAP_UR_9600:
			return CSD_BS_26_NT_V110_9k6;
		default:
			return CSD_BS_NONE;
		}
	}

	if (ra == GSM48_BCAP_RA_V110_X30 && !async && transp) {
		switch (rate) {
		case GSM48_BCAP_UR_1200:
			return CSD_BS_31_T_V110_1k2;
		case GSM48_BCAP_UR_2400:
			return CSD_BS_32_T_V110_2k4;
		case GSM48_BCAP_UR_4800:
			return CSD_BS_33_T_V110_4k8;
		case GSM48_BCAP_UR_9600:
			return CSD_BS_34_T_V110_9k6;
		default:
			return CSD_BS_NONE;
		}
	}

	return CSD_BS_NONE;
}

/* csd_bs_list related below */

int csd_bs_list_to_str_buf(char *buf, size_t buflen, const struct csd_bs_list *list)
{
	struct osmo_strbuf sb = { .buf = buf, .len = buflen };
	int i;

	if (!list->count)
		OSMO_STRBUF_PRINTF(sb, "(no-bearer-services)");

	for (i = 0; i < list->count; i++) {
		if (i)
			OSMO_STRBUF_PRINTF(sb, ",");

		OSMO_STRBUF_APPEND(sb, csd_bs_to_str_buf, list->bs[i]);
	}
	return sb.chars_needed;
}

char *csd_bs_list_to_str_c(void *ctx, const struct csd_bs_list *list)
{
	OSMO_NAME_C_IMPL(ctx, 128, "csd_bs_list_to_str_c-ERROR", csd_bs_list_to_str_buf, list)
}

const char *csd_bs_list_to_str(const struct csd_bs_list *list)
{
	return csd_bs_list_to_str_c(OTC_SELECT, list);
}

bool csd_bs_list_has_bs(const struct csd_bs_list *list, enum csd_bs bs)
{
	int i;

	for (i = 0; i < list->count; i++) {
		if (list->bs[i] == bs)
			return true;
	}

	return false;
}

void csd_bs_list_add_bs(struct csd_bs_list *list, enum csd_bs bs)
{
	int i;

	if (!bs)
		return;

	for (i = 0; i < list->count; i++) {
		if (list->bs[i] == bs)
			return;
	}

	list->bs[i] = bs;
	list->count++;
}

void csd_bs_list_remove(struct csd_bs_list *list, enum csd_bs bs)
{
	int i;
	bool found = false;

	for (i = 0; i < list->count; i++) {
		if (list->bs[i] == bs)
			found = true;
		if (found && i + 1 < list->count)
			list->bs[i] = list->bs[i + 1];
	}

	if (found)
		list->count--;
}

void csd_bs_list_intersection(struct csd_bs_list *dest, const struct csd_bs_list *other)
{
	int i;

	for (i = 0; i < dest->count; i++) {
		if (csd_bs_list_has_bs(other, dest->bs[i]))
			continue;
		csd_bs_list_remove(dest, dest->bs[i]);
		i--;
	}
}

int csd_bs_list_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct csd_bs_list *list)
{
	int i;
	int rc;

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

	if (!list->count)
		return -EINVAL;

	if (csd_bs_is_transp(list->bs[0])) {
		ct->data_transparent = true;
		rc = csd_bs_to_gsm0808_data_rate_transp(list->bs[0], &ct->ch_rate_type);
	} else {
		rc = csd_bs_to_gsm0808_data_rate_non_transp(list->bs[0], &ct->ch_rate_type);
	}

	if (rc < 0)
		return -EINVAL;

	ct->data_rate = rc;

	/* Other possible data rates allowed (3GPP TS 48.008 § 3.2.2.11, 5a) */
	if (!ct->data_transparent && list->count > 1) {
		for (i = 1; i < list->count; i++) {
			if (!csd_bs_is_transp(list->bs[i]))
				continue;

			rc = csd_bs_to_gsm0808_data_rate_non_transp_allowed(list->bs[i]);
			if (rc < 0) {
				LOGP(DMSC, LOGL_DEBUG, "Failed to convert %s to allowed r i/f rate\n",
				     csd_bs_to_str(list->bs[i]));
				continue;
			}

			ct->data_rate_allowed |= rc;
		}
		if (ct->data_rate_allowed)
			ct->data_rate_allowed_is_set = true;
	}

	return 0;
}

int csd_bs_list_to_bearer_cap(struct gsm_mncc_bearer_cap *cap, const struct csd_bs_list *list)
{
	*cap = (struct gsm_mncc_bearer_cap){
		.transfer = GSM_MNCC_BCAP_UNR_DIG,
		.mode = GSM48_BCAP_TMOD_CIRCUIT,
		.coding = GSM48_BCAP_CODING_GSM_STD,
		.radio = GSM48_BCAP_RRQ_FR_ONLY,
	};
	enum csd_bs bs;
	int i;

	for (i = 0; i < list->count; i++) {
		bs = list->bs[i];

		cap->data.rate_adaption = GSM48_BCAP_RA_V110_X30;
		cap->data.sig_access = GSM48_BCAP_SA_I440_I450;
		cap->data.async = bs_map[bs].async;
		if (bs_map[bs].transp)
			cap->data.transp = GSM48_BCAP_TR_TRANSP;
		else
			cap->data.transp = GSM48_BCAP_TR_RLP;

		/* FIXME: proper values for sync/async (current: 8N1) */
		cap->data.nr_data_bits = 8;
		cap->data.parity = GSM48_BCAP_PAR_NONE;
		cap->data.nr_stop_bits = 1;
		cap->data.modem_type = GSM48_BCAP_MT_NONE;

		switch (bs_map[bs].rate) {
		case 300:
			cap->data.user_rate = GSM48_BCAP_UR_300;
			cap->data.interm_rate = GSM48_BCAP_IR_8k;
			break;
		case 1200:
			cap->data.user_rate = GSM48_BCAP_UR_1200;
			cap->data.interm_rate = GSM48_BCAP_IR_8k;
			break;
		case 2400:
			cap->data.user_rate = GSM48_BCAP_UR_2400;
			cap->data.interm_rate = GSM48_BCAP_IR_8k;
			break;
		case 4800:
			cap->data.user_rate = GSM48_BCAP_UR_4800;
			cap->data.interm_rate = GSM48_BCAP_IR_8k;
			break;
		case 9600:
			cap->data.user_rate = GSM48_BCAP_UR_9600;
			cap->data.interm_rate = GSM48_BCAP_IR_16k;
			break;
		default:
			LOGP(DMSC, LOGL_ERROR,
			     "%s(): bs=%d (rate=%u) is not implemented\n",
			     __func__, bs, bs_map[bs].rate);
			continue;
		}

		/* FIXME: handle more than one list entry */
		return 1;
	}

	return 0;
}

void csd_bs_list_from_bearer_cap(struct csd_bs_list *list, const struct gsm_mncc_bearer_cap *cap)
{
	*list = (struct csd_bs_list){};

	switch (cap->data.transp) {
	case GSM48_BCAP_TR_TRANSP:
		csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, true));
		break;
	case GSM48_BCAP_TR_RLP: /* NT */
		csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, false));
		break;
	case GSM48_BCAP_TR_TR_PREF:
		csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, true));
		csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, false));
		break;
	case GSM48_BCAP_TR_RLP_PREF:
		csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, false));
		csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, true));
		break;
	}

	if (!list->count) {
		LOGP(DMSC, LOGL_ERROR, "Failed to get bearer service from bearer capabilities ra=%d, async=%d,"
		     " transp=%d, user_rate=%d\n", cap->data.rate_adaption, cap->data.async, cap->data.transp,
		     cap->data.user_rate);
		return;
	}
}
