/*
 * 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 "../../common/test_common.h"

#include "f32.pat"

#define SNR_ERROR_THRESH	((float32_t)120)
#define REL_ERROR_THRESH	(8.0e-5)

void test_arm_linear_interp_f32(void)
{
	arm_linear_interp_instance_f32 inst;
	size_t index;
	size_t length = ARRAY_SIZE(ref_linear);
	const float32_t *input = (const float32_t *)in_linear_x;
	float32_t *output;

	/* Initialise instance */
	inst.nValues = ARRAY_SIZE(in_linear_y);
	inst.x1 = 0.0;
	inst.xSpacing = 1.0;
	inst.pYData = (float32_t *)in_linear_y;

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

	/* Run test function */
	for (index = 0; index < length; index++) {
		output[index] = arm_linear_interp_f32(&inst,
						      input[index]);
	}

	/* Validate output */
	zassert_true(
		test_snr_error_f32(length, output, (float32_t *)ref_linear,
			SNR_ERROR_THRESH),
		ASSERT_MSG_SNR_LIMIT_EXCEED);

	zassert_true(
		test_rel_error_f32(length, output, (float32_t *)ref_linear,
			REL_ERROR_THRESH),
		ASSERT_MSG_REL_ERROR_LIMIT_EXCEED);

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

void test_arm_bilinear_interp_f32(void)
{
	arm_bilinear_interp_instance_f32 inst;
	size_t index;
	size_t length = ARRAY_SIZE(ref_bilinear);
	const float32_t *input = (const float32_t *)in_bilinear_x;
	float32_t *output;

	/* Initialise instance */
	inst.numRows = in_bilinear_config[1];
	inst.numCols = in_bilinear_config[0];
	inst.pData = (float32_t *)in_bilinear_y;

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

	/* Run test function */
	for (index = 0; index < length; index++) {
		output[index] = arm_bilinear_interp_f32(
					&inst,
					input[2 * index],
					input[2 * index + 1]
					);
	}

	/* Validate output */
	zassert_true(
		test_snr_error_f32(length, output, (float32_t *)ref_bilinear,
			SNR_ERROR_THRESH),
		ASSERT_MSG_SNR_LIMIT_EXCEED);

	zassert_true(
		test_rel_error_f32(length, output, (float32_t *)ref_bilinear,
			REL_ERROR_THRESH),
		ASSERT_MSG_REL_ERROR_LIMIT_EXCEED);

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

static void test_arm_spline(
	const uint32_t *input_x, const uint32_t *input_y,
	const uint32_t *input_xq, const uint32_t *ref, size_t length,
	uint32_t n, arm_spline_type type)
{
	float32_t *output;
	float32_t *scratch;
	float32_t *coeff;
	arm_spline_instance_f32 inst;

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

	/* Allocate scratch buffer */
	scratch = malloc(((n * 2) - 1) * sizeof(float32_t));
	zassert_not_null(scratch, ASSERT_MSG_BUFFER_ALLOC_FAILED);

	/* Allocate coefficient buffer */
	coeff = malloc(((n - 1) * 3) * sizeof(float32_t));
	zassert_not_null(coeff, ASSERT_MSG_BUFFER_ALLOC_FAILED);

	/* Initialise spline */
	arm_spline_init_f32(&inst, type,
		(float32_t *)input_x, (float32_t *)input_y, n, coeff, scratch);

	/* Run test function */
	arm_spline_f32(&inst, (float32_t *)input_xq, output, length);

	/* Validate output */
	zassert_true(
		test_snr_error_f32(length, output, (float32_t *)ref,
			SNR_ERROR_THRESH),
		ASSERT_MSG_SNR_LIMIT_EXCEED);

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

DEFINE_TEST_VARIANT7(arm_spline, square_20,
	in_spline_squ_x, in_spline_squ_y, in_spline_squ_xq, ref_spline_squ, 20,
	4, ARM_SPLINE_PARABOLIC_RUNOUT);

DEFINE_TEST_VARIANT7(arm_spline, sine_33,
	in_spline_sin_x, in_spline_sin_y, in_spline_sin_xq, ref_spline_sin, 33,
	9, ARM_SPLINE_NATURAL);

DEFINE_TEST_VARIANT7(arm_spline, ramp_30,
	in_spline_ram_x, in_spline_ram_y, in_spline_ram_xq, ref_spline_ram, 30,
	3, ARM_SPLINE_PARABOLIC_RUNOUT);

void test_interpolation_f32(void)
{
	ztest_test_suite(interpolation_f32,
		ztest_unit_test(test_arm_linear_interp_f32),
		ztest_unit_test(test_arm_bilinear_interp_f32),
		ztest_unit_test(test_arm_spline_square_20),
		ztest_unit_test(test_arm_spline_sine_33),
		ztest_unit_test(test_arm_spline_ramp_30)
		);

	ztest_run_test_suite(interpolation_f32);
}
