/*
 * Copyright (c) 2021 Stephanos Ioannidis <root@stephanos.io>
 * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ztest.h>
#include <zephyr/zephyr.h>
#include <stdlib.h>
#include <arm_math.h>
#include <arm_const_structs.h>
#include "../../common/test_common.h"

#include "cq15.pat"

#define SNR_ERROR_THRESH_FFT	((float32_t)30)
#define SNR_ERROR_THRESH_IFFT	((float32_t)5)

static void test_arm_cfft_q15(
	const q15_t *input, const q15_t *ref, size_t length)
{
	arm_cfft_instance_q15 inst;
	q15_t *output;
	arm_status status;

	/* Initialise instance */
	status = arm_cfft_init_q15(&inst, length / 2);

	zassert_equal(status, ARM_MATH_SUCCESS,
		      ASSERT_MSG_INCORRECT_COMP_RESULT);

	/* Allocate output buffer */
	output = malloc(length * sizeof(q15_t));
	zassert_not_null(output, ASSERT_MSG_BUFFER_ALLOC_FAILED);

	/* Load data in place */
	memcpy(output, input, length * sizeof(q15_t));

	/* Run test function */
	arm_cfft_q15(&inst, output, false, true);

	/* Validate output */
	zassert_true(
		test_snr_error_q15(length, output, ref, SNR_ERROR_THRESH_FFT),
		ASSERT_MSG_SNR_LIMIT_EXCEED);

	/* Free output buffer */
	free(output);
}

DEFINE_TEST_VARIANT3(arm_cfft_q15, noisy_16,
	in_cfft_noisy_16, ref_cfft_noisy_16, 32);

DEFINE_TEST_VARIANT3(arm_cfft_q15, noisy_32,
	in_cfft_noisy_32, ref_cfft_noisy_32, 64);

DEFINE_TEST_VARIANT3(arm_cfft_q15, noisy_64,
	in_cfft_noisy_64, ref_cfft_noisy_64, 128);

DEFINE_TEST_VARIANT3(arm_cfft_q15, noisy_128,
	in_cfft_noisy_128, ref_cfft_noisy_128, 256);

DEFINE_TEST_VARIANT3(arm_cfft_q15, noisy_256,
	in_cfft_noisy_256, ref_cfft_noisy_256, 512);

DEFINE_TEST_VARIANT3(arm_cfft_q15, noisy_512,
	in_cfft_noisy_512, ref_cfft_noisy_512, 1024);

DEFINE_TEST_VARIANT3(arm_cfft_q15, noisy_1024,
	in_cfft_noisy_1024, ref_cfft_noisy_1024, 2048);

DEFINE_TEST_VARIANT3(arm_cfft_q15, noisy_2048,
	in_cfft_noisy_2048, ref_cfft_noisy_2048, 4096);

DEFINE_TEST_VARIANT3(arm_cfft_q15, noisy_4096,
	in_cfft_noisy_4096, ref_cfft_noisy_4096, 8192);

DEFINE_TEST_VARIANT3(arm_cfft_q15, step_16,
	in_cfft_step_16, ref_cfft_step_16, 32);

DEFINE_TEST_VARIANT3(arm_cfft_q15, step_32,
	in_cfft_step_32, ref_cfft_step_32, 64);

DEFINE_TEST_VARIANT3(arm_cfft_q15, step_64,
	in_cfft_step_64, ref_cfft_step_64, 128);

DEFINE_TEST_VARIANT3(arm_cfft_q15, step_128,
	in_cfft_step_128, ref_cfft_step_128, 256);

DEFINE_TEST_VARIANT3(arm_cfft_q15, step_256,
	in_cfft_step_256, ref_cfft_step_256, 512);

DEFINE_TEST_VARIANT3(arm_cfft_q15, step_512,
	in_cfft_step_512, ref_cfft_step_512, 1024);

DEFINE_TEST_VARIANT3(arm_cfft_q15, step_1024,
	in_cfft_step_1024, ref_cfft_step_1024, 2048);

DEFINE_TEST_VARIANT3(arm_cfft_q15, step_2048,
	in_cfft_step_2048, ref_cfft_step_2048, 4096);

DEFINE_TEST_VARIANT3(arm_cfft_q15, step_4096,
	in_cfft_step_4096, ref_cfft_step_4096, 8192);

static void test_arm_cifft_q15(
	int scale_factor, const q15_t *input, const q15_t *ref, size_t length)
{
	arm_cfft_instance_q15 inst;
	size_t index;
	q15_t *output, *scaled_ref;
	arm_status status;

	/* Initialise instance */
	status = arm_cfft_init_q15(&inst, length / 2);

	zassert_equal(status, ARM_MATH_SUCCESS,
		      ASSERT_MSG_INCORRECT_COMP_RESULT);

	/* Allocate buffers */
	output = malloc(length * sizeof(q15_t));
	zassert_not_null(output, ASSERT_MSG_BUFFER_ALLOC_FAILED);

	scaled_ref = malloc(length * sizeof(q15_t));
	zassert_not_null(scaled_ref, ASSERT_MSG_BUFFER_ALLOC_FAILED);

	/* Load data in place */
	memcpy(output, input, length * sizeof(q15_t));

	/* Run test function */
	arm_cfft_q15(&inst, output, true, true);

	/* Scale reference data */
	for (index = 0; index < length; index++) {
		scaled_ref[index] = ref[index] >> scale_factor;
	}

	/* Validate output */
	zassert_true(
		test_snr_error_q15(length, output, scaled_ref,
			SNR_ERROR_THRESH_IFFT),
		ASSERT_MSG_SNR_LIMIT_EXCEED);

	/* Free output buffer */
	free(output);
	free(scaled_ref);
}

DEFINE_TEST_VARIANT4(arm_cifft_q15, noisy_16, 4,
	in_cifft_noisy_16, in_cfft_noisy_16, 32);

DEFINE_TEST_VARIANT4(arm_cifft_q15, noisy_32, 5,
	in_cifft_noisy_32, in_cfft_noisy_32, 64);

DEFINE_TEST_VARIANT4(arm_cifft_q15, noisy_64, 6,
	in_cifft_noisy_64, in_cfft_noisy_64, 128);

DEFINE_TEST_VARIANT4(arm_cifft_q15, noisy_128, 7,
	in_cifft_noisy_128, in_cfft_noisy_128, 256);

DEFINE_TEST_VARIANT4(arm_cifft_q15, noisy_256, 8,
	in_cifft_noisy_256, in_cfft_noisy_256, 512);

DEFINE_TEST_VARIANT4(arm_cifft_q15, noisy_512, 9,
	in_cifft_noisy_512, in_cfft_noisy_512, 1024);

DEFINE_TEST_VARIANT4(arm_cifft_q15, noisy_1024, 10,
	in_cifft_noisy_1024, in_cfft_noisy_1024, 2048);

DEFINE_TEST_VARIANT4(arm_cifft_q15, noisy_2048, 11,
	in_cifft_noisy_2048, in_cfft_noisy_2048, 4096);

DEFINE_TEST_VARIANT4(arm_cifft_q15, noisy_4096, 12,
	in_cifft_noisy_4096, in_cfft_noisy_4096, 8192);

DEFINE_TEST_VARIANT4(arm_cifft_q15, step_16, 4,
	in_cifft_step_16, in_cfft_step_16, 32);

DEFINE_TEST_VARIANT4(arm_cifft_q15, step_32, 5,
	in_cifft_step_32, in_cfft_step_32, 64);

DEFINE_TEST_VARIANT4(arm_cifft_q15, step_64, 6,
	in_cifft_step_64, in_cfft_step_64, 128);

DEFINE_TEST_VARIANT4(arm_cifft_q15, step_128, 7,
	in_cifft_step_128, in_cfft_step_128, 256);

DEFINE_TEST_VARIANT4(arm_cifft_q15, step_256, 8,
	in_cifft_step_256, in_cfft_step_256, 512);

DEFINE_TEST_VARIANT4(arm_cifft_q15, step_512, 9,
	in_cifft_step_512, in_cfft_step_512, 1024);

DEFINE_TEST_VARIANT4(arm_cifft_q15, step_1024, 10,
	in_cifft_step_1024, in_cfft_step_1024, 2048);

DEFINE_TEST_VARIANT4(arm_cifft_q15, step_2048, 11,
	in_cifft_step_2048, in_cfft_step_2048, 4096);

DEFINE_TEST_VARIANT4(arm_cifft_q15, step_4096, 12,
	in_cifft_step_4096, in_cfft_step_4096, 8192);

void test_transform_cq15(void)
{
	ztest_test_suite(transform_cq15,
		ztest_unit_test(test_arm_cfft_q15_noisy_16),
		ztest_unit_test(test_arm_cifft_q15_noisy_16),
		ztest_unit_test(test_arm_cfft_q15_noisy_32),
		ztest_unit_test(test_arm_cifft_q15_noisy_32),
		ztest_unit_test(test_arm_cfft_q15_noisy_64),
		ztest_unit_test(test_arm_cifft_q15_noisy_64),
		ztest_unit_test(test_arm_cfft_q15_noisy_128),
		ztest_unit_test(test_arm_cifft_q15_noisy_128),
		ztest_unit_test(test_arm_cfft_q15_noisy_256),
		ztest_unit_test(test_arm_cifft_q15_noisy_256),
		ztest_unit_test(test_arm_cfft_q15_noisy_512),
		ztest_unit_test(test_arm_cifft_q15_noisy_512),
		ztest_unit_test(test_arm_cfft_q15_noisy_1024),
		ztest_unit_test(test_arm_cifft_q15_noisy_1024),
		ztest_unit_test(test_arm_cfft_q15_noisy_2048),
		ztest_unit_test(test_arm_cifft_q15_noisy_2048),
		ztest_unit_test(test_arm_cfft_q15_noisy_4096),
		ztest_unit_test(test_arm_cifft_q15_noisy_4096),
		ztest_unit_test(test_arm_cfft_q15_step_16),
		ztest_unit_test(test_arm_cifft_q15_step_16),
		ztest_unit_test(test_arm_cfft_q15_step_32),
		ztest_unit_test(test_arm_cifft_q15_step_32),
		ztest_unit_test(test_arm_cfft_q15_step_64),
		ztest_unit_test(test_arm_cifft_q15_step_64),
		ztest_unit_test(test_arm_cfft_q15_step_128),
		ztest_unit_test(test_arm_cifft_q15_step_128),
		ztest_unit_test(test_arm_cfft_q15_step_256),
		ztest_unit_test(test_arm_cifft_q15_step_256),
		ztest_unit_test(test_arm_cfft_q15_step_512),
		ztest_unit_test(test_arm_cifft_q15_step_512),
		ztest_unit_test(test_arm_cfft_q15_step_1024),
		ztest_unit_test(test_arm_cifft_q15_step_1024),
		ztest_unit_test(test_arm_cfft_q15_step_2048),
		ztest_unit_test(test_arm_cifft_q15_step_2048),
		ztest_unit_test(test_arm_cfft_q15_step_4096),
		ztest_unit_test(test_arm_cifft_q15_step_4096)
		);

	ztest_run_test_suite(transform_cq15);
}
