/* 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 <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;

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


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

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