/* simple test for the debug interface */
/*
 * (C) 2008, 2009 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 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include <osmocom/core/logging.h>
#include <osmocom/core/utils.h>

#include <stdlib.h>

enum {
	DRLL,
	DCC,
	DMM,
};

static int filter_called = 0;
static int select_output = 0;

static const struct log_info_cat default_categories[] = {
	[DRLL] = {
		.name = "DRLL",
		.description = "A-bis Radio Link Layer (RLL)",
		.color = "\033[1;31m",
		.enabled = 1, .loglevel = LOGL_NOTICE,
	},
	[DCC] = {
		.name = "DCC",
		.description = "Layer3 Call Control (CC)",
		.color = "\033[1;32m",
		.enabled = 1, .loglevel = LOGL_NOTICE,
	},
	[DMM] = {
		.name = NULL,
		.description = "Layer3 Mobility Management (MM)",
		.color = "\033[1;33m",
		.enabled = 1, .loglevel = LOGL_NOTICE,
	},
};

static int test_filter(const struct log_context *ctx, struct log_target *target)
{
	filter_called += 1;
	/* omit everything */
	return select_output;
}

const struct log_info log_info = {
	.cat = default_categories,
	.num_cat = ARRAY_SIZE(default_categories),
	.filter_fn = test_filter,
};

extern struct log_info *osmo_log_info;

int main(int argc, char **argv)
{
	struct log_target *stderr_target;

	log_init(&log_info, NULL);
	stderr_target = log_target_create_stderr();
	log_add_target(stderr_target);
	log_set_all_filter(stderr_target, 1);
	log_set_print_filename(stderr_target, 0);
	log_set_print_category(stderr_target, 1);
	log_set_use_color(stderr_target, 0);

	log_parse_category_mask(stderr_target, "DRLL:DCC");
	log_parse_category_mask(stderr_target, "DRLL");

	select_output = 0;

	DEBUGP(DCC, "You should not see this\n");
	if (log_check_level(DMM, LOGL_DEBUG) != 0)
		fprintf(stderr, "log_check_level did not catch this case\n");

	log_parse_category_mask(stderr_target, "DRLL:DCC");
	DEBUGP(DRLL, "You should see this\n");
	OSMO_ASSERT(log_check_level(DRLL, LOGL_DEBUG) != 0);
	DEBUGP(DCC, "You should see this\n");
	OSMO_ASSERT(log_check_level(DCC, LOGL_DEBUG) != 0);
	DEBUGP(DMM, "You should not see this\n");

	OSMO_ASSERT(log_check_level(DMM, LOGL_DEBUG) == 0);
	OSMO_ASSERT(filter_called == 0);

	log_set_all_filter(stderr_target, 0);
	DEBUGP(DRLL, "You should not see this and filter is called\n");
	OSMO_ASSERT(filter_called == 1);
	OSMO_ASSERT(log_check_level(DRLL, LOGL_DEBUG) == 0);
	OSMO_ASSERT(filter_called == 2);

	DEBUGP(DRLL, "You should not see this\n");
	OSMO_ASSERT(filter_called == 3);
	select_output = 1;
	DEBUGP(DRLL, "You should see this\n");
	OSMO_ASSERT(filter_called == 5); /* called twice on output */

	/* Make sure out-of-bounds category maps to DLGLOBAL */
	log_parse_category_mask(stderr_target, "DLGLOBAL,1");
	/* For IDs out of bounds of the overall osmo_log_info array */
	DEBUGP(osmo_log_info->num_cat + 1, "You should see this on DLGLOBAL (a)\n");
	DEBUGP(osmo_log_info->num_cat + 100, "You should see this on DLGLOBAL (b)\n");
	DEBUGP(osmo_log_info->num_cat, "You should see this on DLGLOBAL (c)\n");
	/* For IDs out of bounds of the user categories part */
	DEBUGP(log_info.num_cat + 1, "You should see this on DLGLOBAL (d)\n");
	DEBUGP(log_info.num_cat, "You should see this on DLGLOBAL (e)\n");

	/* Check log_set_category_filter() with internal categories */
	log_parse_category_mask(stderr_target, "DLGLOBAL,3");
	DEBUGP(DLGLOBAL, "You should not see this (DLGLOBAL not on DEBUG)\n");
	log_set_category_filter(stderr_target, DLGLOBAL, 1, LOGL_DEBUG);
	DEBUGP(DLGLOBAL, "You should see this (DLGLOBAL on DEBUG)\n");

	return 0;
}
