/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* Copyright (c) 2025 Brett A C Sheffield <bacs@librecast.net> */

#include "test.h"
#include <state.h>

static int test_state_config_00(void)
{
	char configfile[] = "0000-0004-config.00.conf";
	state_t state = {0};
	const int hexbyt = crypto_sign_PUBLICKEYBYTES * 2;
	int rc;

	rc = state_defaults_set(&state);
	if (!test_assert(rc == 0, "state_defaults_set(), rc = %i", rc))
		return test_status;
	if (!test_assert((state.defaults.flags & CHAN_ENABLE), "state.defaults.flags CHAN_ENABLE"))
		return test_status;
	if (!test_assert((state.defaults.flags & CHAN_JOIN), "state.defaults.flags CHAN_JOIN"))
		return test_status;

	rc = state_parse_configfile(&state, configfile);
	if (!test_assert(rc == 0, "state_parse_config(), rc = %i", rc))
		return test_status;

	/* setting defaults */
	if (!test_assert(state.defaults.dir != NULL, "state.defaults.dir is not NULL"))
		return test_status;
	if (!test_expect("/path/to/dir", state.defaults.dir))
		return test_status;

	/* logfile */
	if (!test_assert(state.logfile != NULL, "state.logfile is not NULL"))
		return test_status;
	if (!test_expect("/path/to/logfile", state.logfile))
		return test_status;

	/* test first default key */
	char auth_key[hexbyt];
	memset(auth_key, 'f', sizeof auth_key);
	if (!test_assert((state.defaults.auth_key != NULL), "state.defaults.auth_key is not NULL"))
		return test_status;
	if (!test_expectn(auth_key, state.defaults.auth_key, hexbyt))
		return test_status;

	/* test second default key */
	char *tmp = state.defaults.auth_key + hexbyt;
	memset(auth_key, 'e', sizeof auth_key);
	if (!test_expectn(auth_key, tmp, hexbyt))
		return test_status;

	if (!test_assert((state.defaults.flags & CHAN_CHROOT), "state.defaults.flags CHAN_CHROOT"))
		return test_status;
	if (!test_assert((state.defaults.flags & CHAN_RELOAD), "state.defaults.flags CHAN_RELOAD"))
		return test_status;
	if (!test_assert((state.defaults.flags & CHAN_RESTART), "state.defaults.flags CHAN_RESTART"))
		return test_status;

	/* channel-specific settings */
	if (!test_assert(state.chan_head != NULL, "state.chan_head is not NULL"))
		return test_status;

	state_chan_t *achan;
	char *chan_name[] = { "I Can't Breathe", "BlackLivesMatter" };
	char *chan_dir[] = { "/path/to/other/dir", "3" };
	int channels = sizeof chan_name / sizeof chan_name[0];

	for (int i = 0; i < channels; i++) {
		achan = state_chan_by_name(&state, chan_name[i]);
		if (!test_assert(achan != NULL, "found channel: %s", chan_name[i]))
			return test_status;
		if (!test_expect(chan_dir[i], achan->dir))
			return test_status;
		if (!test_assert(achan->auth_key != NULL, "chan[%i] auth_key set", i))
			return test_status;

		for (unsigned int n = 0; n < achan->auth_keys; n++) {
			memset(auth_key, i + n + 48, sizeof auth_key);
			tmp = achan->auth_key + hexbyt * n;
			if (!test_expectn(auth_key, tmp, hexbyt)) return test_status;
		}
	}

	free_state(&state);

	return test_status;
}

int main(void)
{
	char name[] = "state_parse_config()";

	test_name(name);

	if (test_state_config_00()) return test_status;

	return test_status;
}
