/* 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)
{
	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
	struct gprs_rlcmac_trx *trx;
	int i;

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

	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);
	}
	talloc_free(bts);
}

static inline void test_multislot_total_descending(bool seq)
{
	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
	struct gprs_rlcmac_trx *trx;
	int i;

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

	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);
	}
	talloc_free(bts);
}

static inline void test_multislot_middle(bool seq)
{
	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
	struct gprs_rlcmac_trx *trx;

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

	trx = &bts->trx[0];

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

	test_all_classes(trx, seq);
	talloc_free(bts);
}

static inline void test_multislot_ends(bool seq)
{
	struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
	struct gprs_rlcmac_trx *trx;

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

	trx = &bts->trx[0];

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

	test_all_classes(trx, seq);
	talloc_free(bts);
}

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_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
	log_set_log_level(osmo_stderr_target, LOGL_DEBUG);

	the_pcu = gprs_pcu_alloc(tall_pcu_ctx);

	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();

	talloc_free(the_pcu);

	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(); }
}
