// Copyright 2025 RnD Center "ELVEES", JSC

/*! \file
 *  \brief Тестирование обратного БПФ для типа float
 */

#include "test.h"

int test_ifft_float_1d(const int fft_min_size, const int fft_max_size) {
  int error_count = 0;
  int freq = 5;
  float *dst = memalign(fft_max_size * 2 * sizeof(float), fft_max_size * 2 * sizeof(float));
  float *src = memalign(fft_max_size * 2 * sizeof(float), fft_max_size * 2 * sizeof(float));
  float *fetalon = memalign(fft_max_size * 2 * sizeof(float), fft_max_size * 2 * sizeof(float));

  char *test_info = malloc(sizeof(char) * 1000000);
  int print_bytes;

  FILE *res_1d;
  if (MEM_TYPE == SL_DDR)
    res_1d = fopen("test_FLOAT_IFFT_1D_DDR.csv", "w");
  else
    res_1d = fopen("test_FLOAT_IFFT_1D_XYRAM.csv", "w");

  fprintf(res_1d, "%s,%s,%s,%s\n", "SIZE", "TIC_CNTR", "INSTR_CNTR", "STATUS");

  print_bytes = sprintf(test_info, "float IFFT ");
  if (MEM_TYPE == SL_DDR)
    print_bytes += sprintf(test_info + print_bytes, "DDR\n\n");
  else
    print_bytes += sprintf(test_info + print_bytes, "XYRAM\n\n");

  int retval = SL_SUCCESS;
  for (int size = fft_min_size; size <= fft_max_size; size <<= 1) {
    if (retval) break;
    print_bytes += sprintf(test_info + print_bytes, "\nsize = %d \n", size);
    fprintf(res_1d, "%d,", size);

    for (freq = 1; freq <= 1; ++freq) {
      fft_t fft_obj;
      fft_obj.src = src;
      fft_obj.dst = dst;
      fft_obj.int_mem = (enum sl_data_memory)MEM_TYPE;
      fft_obj.dir = SL_IFFT;
      fft_obj.dim = SL_1D;

      retval = fft_plan_1d(&fft_obj, size, SL_FLOAT);
      if (retval) {
        print_error_message(retval);
        error_count = 1;
        break;
      }

      create_spectrum(fetalon, size, freq, 1.0);

      memset(src, 0., 2 * fft_max_size * sizeof(float));
      src[2 * freq + 1] = (float)size;

      retval = fft_execute(&fft_obj);
      if (retval) {
        print_error_message(retval);
        error_count = 1;

        fft_free_sources(&fft_obj);
        break;
      }

      print_bytes += sprintf(test_info + print_bytes, "\nfreq = %d ..... ", freq);
      print_bytes += sprintf(test_info + print_bytes, "ticks_fft = %d, instr_fft = %d", fft_obj.ticks, fft_obj.instrs);
      fprintf(res_1d, "%d,%d,", fft_obj.ticks, fft_obj.instrs);
      if (!fft_obj.big_size || !fft_obj.int_mem) {
        for (size_t i = 0; i < 2 * size; ++i) dst[i] /= size;

        float norm = maximum_norm(dst, fetalon, size);
        print_bytes += sprintf(test_info + print_bytes, ", norm = %f ", norm);
        if (norm < 1e-1) {
          print_bytes += sprintf(test_info + print_bytes, " : OK\n\n");
          fprintf(res_1d, "%s\n", "passed");
        } else {
          ++error_count;
          print_bytes += sprintf(test_info + print_bytes, " : WRONG\n\n");
          fprintf(res_1d, "%s\n", "failed");
        }
      } else {
        for (size_t i = 0; i < 2 * size; ++i) src[i] /= size;

        float norm = maximum_norm(src, fetalon, size);
        print_bytes += sprintf(test_info + print_bytes, ", norm = %f ", norm);
        if (norm < 1e-1) {
          print_bytes += sprintf(test_info + print_bytes, " : OK\n\n");
          fprintf(res_1d, "%s\n", "passed");
        } else {
          ++error_count;
          print_bytes += sprintf(test_info + print_bytes, " : WRONG\n\n");
          fprintf(res_1d, "%s\n", "failed");
        }
      }

      fft_free_sources(&fft_obj);
    }
  }

  printf("%s", test_info);

  free(test_info);
  free(src);
  free(dst);
  free(fetalon);
  fclose(res_1d);
  return error_count;
}
