/*
 * (C) 2012 by Holger Hans Peter Freyther <zecke@selfish.org>
 * All Rights Reserved
 *
 * 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 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 <stdio.h>
#include <stdlib.h>

#include <osmocom/core/application.h>
#include <osmocom/core/utils.h>
#include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmocom/gsm/gsm23003.h>

#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/abis_nm.h>
#include <osmocom/bsc/debug.h>

static const uint8_t load_config[] = {
	0x42, 0x12, 0x00, 0x08, 0x31, 0x36, 0x38, 0x64,
	0x34, 0x37, 0x32, 0x00, 0x13, 0x00, 0x0b, 0x76,
	0x32, 0x30, 0x30, 0x62, 0x31, 0x34, 0x33, 0x64,
	0x30, 0x00, 0x42, 0x12, 0x00, 0x08, 0x31, 0x36,
	0x38, 0x64, 0x34, 0x37, 0x32, 0x00, 0x13, 0x00,
	0x0b, 0x76, 0x32, 0x30, 0x30, 0x62, 0x31, 0x34,
	0x33, 0x64, 0x31, 0x00
};

static void test_sw_selection(void)
{
	struct abis_nm_sw_desc descr[8], tmp;
	uint16_t len0, len1;
	int rc, pos;

	rc = abis_nm_get_sw_conf(load_config, ARRAY_SIZE(load_config),
				&descr[0], ARRAY_SIZE(descr));
	if (rc != 2) {
		printf("%s(): FAILED to parse the File Id/File version: %d\n",
		       __func__, rc);
		abort();
	}

	len0 = abis_nm_sw_desc_len(&descr[0], true);
	printf("len: %u\n", len0);
	printf("file_id:  %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len));
	printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len));

	len1 = abis_nm_sw_desc_len(&descr[1], true);
	printf("len: %u\n", len1);
	printf("file_id:  %s\n", osmo_hexdump(descr[1].file_id, descr[1].file_id_len));
	printf("file_ver: %s\n", osmo_hexdump(descr[1].file_version, descr[1].file_version_len));

	/* start */
	pos = abis_nm_select_newest_sw(descr, rc);
	if (pos != 1) {
		printf("Selected the wrong version: %d\n", pos);
		abort();
	}
	printf("SELECTED: %d\n", pos);

	/* shuffle */
	tmp = descr[0];
	descr[0] = descr[1];
	descr[1] = tmp;
	pos = abis_nm_select_newest_sw(descr, rc);
	if (pos != 0) {
		printf("Selected the wrong version: %d\n", pos);
		abort();
	}
	printf("SELECTED: %d\n", pos);
	printf("%s(): OK\n", __func__);
}

struct test_abis_nm_ipaccess_cgi {
	struct osmo_plmn_id plmn;
	uint16_t lac;
	uint16_t cell_identity;
	const char *expect;
};
static const struct test_abis_nm_ipaccess_cgi test_abis_nm_ipaccess_cgi_data[] = {
	{
		.plmn = { .mcc = 1, .mnc = 2, .mnc_3_digits = false },
		.lac = 3,
		.cell_identity = 4,
		.expect = "00f120" "0003" "0004",
	},
	{
		.plmn = { .mcc = 1, .mnc = 2, .mnc_3_digits = true },
		.lac = 3,
		.cell_identity = 4,
		.expect = "00f120" /* FAIL: should be "002100" */
			"0003" "0004",
	},
	{
		.plmn = { .mcc = 0, .mnc = 0, .mnc_3_digits = false },
		.lac = 0,
		.cell_identity = 0,
		.expect = "00f000" "0000" "0000",
	},
	{
		.plmn = { .mcc = 0, .mnc = 0, .mnc_3_digits = true },
		.lac = 0,
		.cell_identity = 0,
		.expect = "00f000" /* FAIL: should be "000000" */
			"0000" "0000",
	},
	{
		.plmn = { .mcc = 999, .mnc = 999, .mnc_3_digits = false },
		.lac = 65535,
		.cell_identity = 65535,
		.expect = "999999" "ffff" "ffff",
	},
	{
		.plmn = { .mcc = 909, .mnc = 90, .mnc_3_digits = false },
		.lac = 0xabcd,
		.cell_identity = 0x2345,
		.expect = "09f909" "abcd" "2345",
	},
	{
		.plmn = { .mcc = 909, .mnc = 90, .mnc_3_digits = true },
		.lac = 0xabcd,
		.cell_identity = 0x2345,
		.expect = "09f909" /* FAIL: should be "090990" */
			"abcd" "2345",
	},
};

static void test_abis_nm_ipaccess_cgi()
{
	int i;
	bool pass = true;

	for (i = 0; i < ARRAY_SIZE(test_abis_nm_ipaccess_cgi_data); i++) {
		struct gsm_network net;
		struct gsm_bts bts;
		const struct test_abis_nm_ipaccess_cgi *t = &test_abis_nm_ipaccess_cgi_data[i];
		uint8_t result_buf[7] = {};
		char *result;
		bool ok;

		net.country_code = t->plmn.mcc;
		net.network_code = t->plmn.mnc;
		bts.network = &net;
		bts.location_area_code = t->lac;
		bts.cell_identity = t->cell_identity;

		abis_nm_ipaccess_cgi(result_buf, &bts);
		result = osmo_hexdump_nospc(result_buf, sizeof(result_buf));

		ok = (strcmp(result, t->expect) == 0);
		printf("%s[%d]: result=%s %s\n", __func__, i, result, ok ? "pass" : "FAIL");
		pass = pass && ok;
	}

	OSMO_ASSERT(pass);
}


static const struct log_info_cat log_categories[] = {
};

static const struct log_info log_info = {
	.cat = log_categories,
	.num_cat = ARRAY_SIZE(log_categories),
};

int main(int argc, char **argv)
{
	osmo_init_logging(&log_info);

	test_sw_selection();
	test_abis_nm_ipaccess_cgi();

	return EXIT_SUCCESS;
}
