/*
 * Copyright (c) 2021 Arm Limited. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "RNNoiseModel.hpp"
#include "UseCaseHandler.hpp"
#include "InputFiles.hpp"
#include "RNNUCTestCaseData.hpp"
#include "UseCaseCommonUtils.hpp"

#include <catch.hpp>
#include <hal.h>
#include <Profiler.hpp>
#include <iostream>
#define PLATFORM \
hal_platform    platform; \
data_acq_module data_acq; \
data_psn_module data_psn; \
platform_timer  timer;    \
hal_init(&platform, &data_acq, &data_psn, &timer); \
hal_platform_init(&platform);

#define CONTEXT \
arm::app::ApplicationContext caseContext; \
arm::app::Profiler profiler{&platform, "noise_reduction"}; \
caseContext.Set<arm::app::Profiler&>("profiler", profiler); \
caseContext.Set<hal_platform&>("platform", platform); \
caseContext.Set<arm::app::RNNoiseModel&>("model", model);

TEST_CASE("Verify output tensor memory dump")
{
    constexpr size_t maxMemDumpSz = 0x100000;   /* 1 MiB worth of space */
    std::vector<uint8_t> memPool(maxMemDumpSz); /* Memory pool */
    arm::app::RNNoiseModel model{};

    REQUIRE(model.Init());
    REQUIRE(model.IsInited());

    /* Populate the output tensors */
    const size_t numOutputs = model.GetNumOutputs();
    size_t sizeToWrite = 0;
    size_t lastTensorSize = model.GetOutputTensor(numOutputs - 1)->bytes;

    for (size_t i = 0; i < numOutputs; ++i) {
        TfLiteTensor* tensor = model.GetOutputTensor(i);
        auto* tData = tflite::GetTensorData<uint8_t>(tensor);

        if (tensor->bytes > 0) {
            memset(tData, static_cast<uint8_t>(i), tensor->bytes);
            sizeToWrite += tensor->bytes;
        }
    }


    SECTION("Positive use case")
    {
        /* Run the memory dump */
        auto bytesWritten = DumpOutputTensorsToMemory(model, memPool.data(), memPool.size());
        REQUIRE(sizeToWrite == bytesWritten);

        /* Verify the dump */
        size_t k = 0;
        for (size_t i = 0; i < numOutputs && k < memPool.size(); ++i) {
            TfLiteTensor* tensor = model.GetOutputTensor(i);
            auto* tData = tflite::GetTensorData<uint8_t>(tensor);

            for (size_t j = 0; j < tensor->bytes && k < memPool.size(); ++j) {
                REQUIRE(tData[j] == memPool[k++]);
            }
        }
    }

    SECTION("Limited memory - skipping last tensor")
    {
        /* Run the memory dump */
        auto bytesWritten = DumpOutputTensorsToMemory(model, memPool.data(), sizeToWrite - 1);
        REQUIRE(lastTensorSize > 0);
        REQUIRE(bytesWritten == sizeToWrite - lastTensorSize);
    }

    SECTION("Zero memory")
    {
        /* Run the memory dump */
        auto bytesWritten = DumpOutputTensorsToMemory(model, memPool.data(), 0);
        REQUIRE(bytesWritten == 0);
    }
}

TEST_CASE("Inference run all clips", "[RNNoise]")
{
    PLATFORM

    arm::app::RNNoiseModel model;

    CONTEXT

    caseContext.Set<uint32_t>("clipIndex", 0);
    caseContext.Set<uint32_t>("numInputFeatures", g_NumInputFeatures);
    caseContext.Set<uint32_t>("frameLength", g_FrameLength);
    caseContext.Set<uint32_t>("frameStride", g_FrameStride);

    /* Load the model. */
    REQUIRE(model.Init());

    REQUIRE(arm::app::NoiseReductionHandler(caseContext, true));
}

std::function<uint32_t(const uint32_t)> get_golden_input_p232_208_array_size(const uint32_t numberOfFeatures) {

    return [numberOfFeatures](const uint32_t) ->  uint32_t{
        return numberOfFeatures;
    };
}

const char* get_test_filename(const uint32_t idx) {
    auto name = get_filename(idx);
    REQUIRE(std::string("p232_208.wav") == name);
    return "p232_208.wav";
}

void testInfByIndex(std::vector<uint32_t>& numberOfInferences) {
    PLATFORM

    arm::app::RNNoiseModel model;

    CONTEXT

    caseContext.Set<std::function<const int16_t*(const uint32_t)>>("features", get_audio_array);
    caseContext.Set<std::function<const char* (const uint32_t)>>("featureFileNames", get_test_filename);
    caseContext.Set<uint32_t>("frameLength", g_FrameLength);
    caseContext.Set<uint32_t>("frameStride", g_FrameStride);
    caseContext.Set<uint32_t>("numInputFeatures", g_NumInputFeatures);
    /* Load the model. */
    REQUIRE(model.Init());

    size_t oneInferenceOutSizeBytes = g_FrameLength * sizeof(int16_t);

    auto infIndex = 0;
    for (auto numInf: numberOfInferences) {
        DYNAMIC_SECTION("Number of features: "<< numInf) {
            caseContext.Set<uint32_t>("clipIndex", 1);  /* Only getting p232_208.wav for tests. */
            uint32_t audioSizeInput = numInf*g_FrameLength;
            caseContext.Set<std::function<uint32_t(const uint32_t)>>("featureSizes",
                                                                     get_golden_input_p232_208_array_size(audioSizeInput));

            size_t headerNumBytes = 4 + 12 + 4;  /* Filename length, filename (12 for p232_208.wav), dump size. */
            size_t footerNumBytes = 4;  /* Eof value. */
            size_t memDumpMaxLenBytes = headerNumBytes + footerNumBytes + oneInferenceOutSizeBytes * numInf;

            std::vector<uint8_t > memDump(memDumpMaxLenBytes);
            size_t undefMemDumpBytesWritten = 0;
            caseContext.Set<size_t>("MEM_DUMP_LEN", memDumpMaxLenBytes);
            caseContext.Set<uint8_t*>("MEM_DUMP_BASE_ADDR", memDump.data());
            caseContext.Set<size_t*>("MEM_DUMP_BYTE_WRITTEN", &undefMemDumpBytesWritten);

            /* Inference. */
            REQUIRE(arm::app::NoiseReductionHandler(caseContext, false));

            /* The expected output after post-processing. */
            std::vector<int16_t> golden(&ofms[infIndex][0], &ofms[infIndex][0] + g_FrameLength);

            size_t startOfLastInfOut = undefMemDumpBytesWritten - oneInferenceOutSizeBytes;

            /* The actual result from the usecase handler. */
            std::vector<int16_t> runtime(g_FrameLength);
            std::memcpy(runtime.data(), &memDump[startOfLastInfOut], oneInferenceOutSizeBytes);

            /* Margin of 22 is 0.03% error. */
            REQUIRE_THAT(golden, Catch::Matchers::Approx(runtime).margin(22));
        }
        ++infIndex;
    }
}

TEST_CASE("Inference by index - one inference", "[RNNoise]")
{
    auto totalAudioSize = get_audio_array_size(1);
    REQUIRE(64757 == totalAudioSize);  /* Checking that the input file is as expected and has not changed. */

    /* Run 1 inference */
    std::vector<uint32_t> numberOfInferences = {1};
    testInfByIndex(numberOfInferences);
}

TEST_CASE("Inference by index - several inferences", "[RNNoise]")
{
    auto totalAudioSize = get_audio_array_size(1);
    REQUIRE(64757 == totalAudioSize);  /* Checking that the input file is as expected and has not changed. */

    /* 3 different inference amounts: 1, 2 and all inferences required to cover total feature set */
    uint32_t totalInferences = totalAudioSize / g_FrameLength;
    std::vector<uint32_t> numberOfInferences = {1, 2, totalInferences};
    testInfByIndex(numberOfInferences);
}
