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

#include "InputFiles.hpp"

namespace arm {
namespace app {

    bool RunInference(hal_platform& platform, arm::app::Model& model)
    {
        Profiler profiler{&platform, "Inference"};
        profiler.StartProfiling();

        bool runInf = model.RunInference();

        profiler.StopProfiling();
        std::string profileResults = profiler.GetResultsAndReset();
        info("%s\n", profileResults.c_str());

        return runInf;
    }

    int ReadUserInputAsInt(hal_platform& platform)
    {
        char chInput[128];
        memset(chInput, 0, sizeof(chInput));

        platform.data_acq->get_input(chInput, sizeof(chInput));
        return atoi(chInput);
    }

    void DumpTensor(TfLiteTensor* tensor, const size_t lineBreakForNumElements)
    {
        char strhex[8];
        std::string strdump;

        if (!tensor) {
            printf_err("invalid tensor\n");
            return;
        }

        const uint32_t tensorSz = tensor->bytes;
        const uint8_t* tensorData = tflite::GetTensorData<uint8_t>(tensor);

        for (size_t i = 0; i < tensorSz; ++i) {
            if (0 == i % lineBreakForNumElements) {
                printf("%s\n\t", strdump.c_str());
                strdump.clear();
            }
            snprintf(strhex, sizeof(strhex) - 1,
                     "0x%02x, ", tensorData[i]);
            strdump += std::string(strhex);
        }

        if (strdump.size()) {
            printf("%s\n", strdump.c_str());
        }
    }

    bool ListFilesHandler(ApplicationContext& ctx)
    {
        auto& model = ctx.Get<Model&>("model");
        auto& platform = ctx.Get<hal_platform&>("platform");

        constexpr uint32_t dataPsnTxtStartX = 20;
        constexpr uint32_t dataPsnTxtStartY = 40;

        if (!model.IsInited()) {
            printf_err("Model is not initialised! Terminating processing.\n");
            return false;
        }

        /* Clear the LCD */
        platform.data_psn->clear(COLOR_BLACK);

        /* Show the total number of embedded files. */
        std::string strNumFiles = std::string{"Total Number of Files: "} +
                                   std::to_string(NUMBER_OF_FILES);
        platform.data_psn->present_data_text(strNumFiles.c_str(),
                                             strNumFiles.size(),
                                             dataPsnTxtStartX,
                                             dataPsnTxtStartY,
                                             0);

#if NUMBER_OF_FILES > 0
        constexpr uint32_t dataPsnTxtYIncr = 16;
        info("List of Files:\n");
        uint32_t yVal = dataPsnTxtStartY + dataPsnTxtYIncr;
        for (uint32_t i = 0; i < NUMBER_OF_FILES; ++i, yVal += dataPsnTxtYIncr) {

            std::string currentFilename{get_filename(i)};
            platform.data_psn->present_data_text(currentFilename.c_str(),
                                                 currentFilename.size(),
                                                 dataPsnTxtStartX, yVal, 0);

            info("\t%u => %s\n", i, currentFilename.c_str());
        }
#endif /* NUMBER_OF_FILES > 0 */

        return true;
    }

} /* namespace app */
} /* namespace arm */