/*
 * 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 "Wav2LetterPreprocess.hpp"

#include <limits>
#include <algorithm>
#include <catch.hpp>

constexpr uint32_t numMfccFeatures = 13;
constexpr uint32_t numMfccVectors  = 10;

/* Test vector output: generated using test-asr-preprocessing.py. */
int8_t expectedResult[numMfccVectors][numMfccFeatures * 3] = {
    /* Feature vec 0. */
    -32,   4,  -9,  -8, -10, -10, -11, -11, -11, -11, -12, -11, -11,    /* MFCCs.   */
    -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,    /* Delta 1. */
    -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,    /* Delta 2. */

    /* Feature vec 1. */
    -31,   4,  -9,  -8, -10, -10, -11, -11, -11, -11, -12, -11, -11,
    -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
    -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,

    /* Feature vec 2. */
    -31,   4,  -9,  -9, -10, -10, -11, -11, -11, -11, -12, -12, -12,
    -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
    -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,

    /* Feature vec 3. */
    -31,   4,  -9,  -9, -10, -10, -11, -11, -11, -11, -11, -12, -12,
    -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
    -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,

    /* Feature vec 4 : this should have valid delta 1 and delta 2. */
    -31,   4,  -9,  -9, -10, -10, -11, -11, -11, -11, -11, -12, -12,
    -38, -29,  -9,   1,  -2,  -7,  -8,  -8, -12, -16, -14,  -5,   5,
    -68, -50, -13,   5,   0,  -9,  -9,  -8, -13, -20, -19,  -3,  15,

    /* Feature vec 5 : this should have valid delta 1 and delta 2. */
    -31,   4,  -9,  -8, -10, -10, -11, -11, -11, -11, -11, -12, -12,
    -62, -45, -11,   5,   0,  -8,  -9,  -8, -12, -19, -17,  -3,  13,
    -27, -22, -13,  -9, -11, -12, -12, -11, -11, -13, -13, -10,  -6,

    /* Feature vec 6. */
    -31,   4,  -9,  -8, -10, -10, -11, -11, -11, -11, -12, -11, -11,
    -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
    -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,

    /* Feature vec 7. */
    -32,   4,  -9,  -8, -10, -10, -11, -11, -11, -12, -12, -11, -11,
    -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
    -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,

    /* Feature vec 8. */
    -32,   4,  -9,  -8, -10, -10, -11, -11, -11, -12, -12, -11, -11,
    -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
    -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,

    /* Feature vec 9. */
    -31,   4,  -9,  -8, -10, -10, -11, -11, -11, -11, -12, -11, -11,
    -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
    -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10
};

void PopulateTestWavVector(std::vector<int16_t>& vec)
{
    constexpr int int16max = std::numeric_limits<int16_t>::max();
    int val = 0;
    for (size_t i = 0; i < vec.size(); ++i, ++val) {

        /* We want a differential filter response from both - order 1
         * and 2 => Don't have a linear signal here - we use a signal
         * using squares for example. Alternate sign flips might work
         * just as well and will be computationally less work! */
        int valsq = val * val;
        if (valsq > int16max) {
            val = 0;
            valsq = 0;
        }
        vec[i] = valsq;
    }
}

TEST_CASE("Preprocessing calculation INT8")
{
    /* Initialise the HAL and 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);

    /* Constants. */
    const uint32_t  windowLen       = 512;
    const uint32_t  windowStride    = 160;
    int             dimArray[]      = {3, 1, numMfccFeatures * 3, numMfccVectors};
    const float     quantScale      = 0.1410219967365265;
    const int       quantOffset     = -11;

    /* Test wav memory. */
    std::vector <int16_t> testWav((windowStride * numMfccVectors) +
                                  (windowLen - windowStride));

    /* Populate with dummy input. */
    PopulateTestWavVector(testWav);

    /* Allocate mem for tensor. */
    std::vector<int8_t> tensorVec(dimArray[1]*dimArray[2]*dimArray[3]);

    /* Initialise dimensions and the test tensor. */
    TfLiteIntArray* dims= tflite::testing::IntArrayFromInts(dimArray);
    TfLiteTensor tensor = tflite::testing::CreateQuantizedTensor(
        tensorVec.data(), dims, quantScale, quantOffset, "preprocessedInput");

    /* Initialise pre-processing module. */
    arm::app::audio::asr::Preprocess prep{
        numMfccFeatures, windowLen, windowStride, numMfccVectors};

    /* Invoke pre-processing. */
    REQUIRE(prep.Invoke(testWav.data(), testWav.size(), &tensor));

    /* Wrap the tensor with a std::vector for ease. */
    int8_t * tensorData = tflite::GetTensorData<int8_t>(&tensor);
    std::vector <int8_t> vecResults =
        std::vector<int8_t>(tensorData, tensorData + tensor.bytes);

    /* Check sizes. */
    REQUIRE(vecResults.size() == sizeof(expectedResult));

    /* Check that the elements have been calculated correctly. */
    for (uint32_t j = 0; j < numMfccVectors; ++j) {
        for (uint32_t i = 0; i < numMfccFeatures * 3; ++i) {
            size_t tensorIdx = (j * numMfccFeatures * 3) + i;
            CHECK(vecResults[tensorIdx] == expectedResult[j][i]);
        }
    }
}
