/* MslotTest.cpp
 *
 * Copyright (C) 2017 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include "gprs_rlcmac.h"
#include "gprs_debug.h"
#include "tbf.h"
#include "bts.h"

#include <string.h>
#include <stdio.h>
#include <errno.h>

extern "C" {
	#include "mslot_class.h"
#include <osmocom/core/application.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
}

/* globals used by the code */
void *tall_pcu_ctx;
int16_t spoof_mnc = 0, spoof_mcc = 0;
bool spoof_mnc_3_digits = false;

static inline void test_all_classes(struct gprs_rlcmac_trx *trx, bool clear_masks)
{
	int i, rc;
	uint8_t dl_slots = 0, ul_slots = 0;

	for (i = 0; i < 64; i++) {
		rc = find_multi_slots(trx, i, &ul_slots, &dl_slots);

		printf("    [%s] multislot class %3u - UL: " OSMO_BIT_SPEC " DL: " OSMO_BIT_SPEC " [%d]\n",
		       clear_masks ? "SEQ" : "ACC", i, OSMO_BIT_PRINT(ul_slots), OSMO_BIT_PRINT(dl_slots), rc);

		if (rc == -EINVAL)
			return;

		if (clear_masks) {
			dl_slots = 0;
			ul_slots = 0;
		}
	}
}

static inline void test_multislot_total_ascending(bool seq)
{
	BTS the_bts;
	struct gprs_rlcmac_bts *bts;
	struct gprs_rlcmac_trx *trx;
	int i;

	printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");

	bts = the_bts.bts_data();

	trx = &bts->trx[0];

	for (i = 0; i < 8; i++) {
		printf("  Enabled PDCH %u for multislot tests...\n", i);
		trx->pdch[i].enable();

		test_all_classes(trx, seq);
	}
}

static inline void test_multislot_total_descending(bool seq)
{
	BTS the_bts;
	struct gprs_rlcmac_bts *bts;
	struct gprs_rlcmac_trx *trx;
	int i;

	printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");

	bts = the_bts.bts_data();

	trx = &bts->trx[0];

	for (i = 7; i >= 0; i--) {
		printf("  Enabled PDCH %u for multislot tests...\n", i);
		trx->pdch[i].enable();

		test_all_classes(trx, seq);
	}
}

static inline void test_multislot_middle(bool seq)
{
	BTS the_bts;
	struct gprs_rlcmac_bts *bts;
	struct gprs_rlcmac_trx *trx;

	printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");

	bts = the_bts.bts_data();

	trx = &bts->trx[0];

	trx->pdch[2].enable();
	trx->pdch[3].enable();
	trx->pdch[4].enable();

	test_all_classes(trx, seq);
}

static inline void test_multislot_ends(bool seq)
{
	BTS the_bts;
	struct gprs_rlcmac_bts *bts;
	struct gprs_rlcmac_trx *trx;

	printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");

	bts = the_bts.bts_data();

	trx = &bts->trx[0];

	trx->pdch[0].enable();
	trx->pdch[7].enable();

	test_all_classes(trx, seq);
}

static inline void test_window_wrapper()
{
	uint16_t i;
	for (i = 0; i < 256 * 2 + 1; i++)
		printf("W[%03u] -> %3u %s\n",
		       i, mslot_wrap_window(i), mslot_wrap_window(i) < 256 ? "OK" : "FAIL");
}

int main(int argc, char **argv)
{
	tall_pcu_ctx = talloc_named_const(NULL, 1, "MslotTest context");
	if (!tall_pcu_ctx)
		abort();

	msgb_talloc_ctx_init(tall_pcu_ctx, 0);

	osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
	log_set_use_color(osmo_stderr_target, 0);
	log_set_print_filename(osmo_stderr_target, 0);
	log_set_log_level(osmo_stderr_target, LOGL_DEBUG);

	test_multislot_total_ascending(true);
	test_multislot_total_ascending(false);

	test_multislot_total_descending(true);
	test_multislot_total_descending(false);

	test_multislot_middle(true);
	test_multislot_middle(false);

	test_multislot_ends(true);
	test_multislot_ends(false);

	test_window_wrapper();

	return EXIT_SUCCESS;
}

/*
 * stubs that should not be reached
 */
extern "C" {
void l1if_pdch_req() { abort(); }
void l1if_connect_pdch() { abort(); }
void l1if_close_pdch() { abort(); }
void l1if_open_pdch() { abort(); }
}
