/*
 * Copyright (c) 2020-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
 *
 * 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.
 */

/****************************************************************************
 * Includes
 ****************************************************************************/

// FreeRTOS
#include "FreeRTOS.h"
#include "queue.h"
#include "task.h"

// Ethos-U
#include "ethosu_driver.h"
#include "inference_process.hpp"

// System includes
#include <stdio.h>

using namespace std;
using namespace InferenceProcess;

/****************************************************************************
 * InferenceJob
 ****************************************************************************/

#define TENSOR_ARENA_SIZE 0xa0000

__attribute__((section(".bss.NoInit"), aligned(16))) uint8_t inferenceProcessTensorArena[TENSOR_ARENA_SIZE];

namespace {

struct xInferenceJob : public InferenceJob {
    QueueHandle_t queue;
    bool status;

    xInferenceJob();
    xInferenceJob(const string &name,
                  const DataPtr &networkModel,
                  const vector<DataPtr> &input,
                  const vector<DataPtr> &output,
                  const vector<DataPtr> &expectedOutput,
                  size_t numBytesToPrint,
                  const vector<uint8_t> &pmuEventConfig,
                  const uint32_t pmuCycleCounterEnable,
                  QueueHandle_t queue);
};

xInferenceJob::xInferenceJob() : InferenceJob(), queue(nullptr), status(false) {}

xInferenceJob::xInferenceJob(const std::string &_name,
                             const DataPtr &_networkModel,
                             const std::vector<DataPtr> &_input,
                             const std::vector<DataPtr> &_output,
                             const std::vector<DataPtr> &_expectedOutput,
                             size_t _numBytesToPrint,
                             const vector<uint8_t> &_pmuEventConfig,
                             const uint32_t _pmuCycleCounterEnable,
                             QueueHandle_t _queue) :
    InferenceJob(_name,
                 _networkModel,
                 _input,
                 _output,
                 _expectedOutput,
                 _numBytesToPrint,
                 _pmuEventConfig,
                 _pmuCycleCounterEnable),
    queue(_queue), status(false) {}

} // namespace

/****************************************************************************
 * Functions
 ****************************************************************************/

namespace {

#include "model.h"
#include "input.h"
#include "output.h"

void inferenceProcessTask(void *pvParameters) {
    QueueHandle_t queue = reinterpret_cast<QueueHandle_t>(pvParameters);

    class InferenceProcess inferenceProcess(inferenceProcessTensorArena, TENSOR_ARENA_SIZE);

    while (true) {
        xInferenceJob *job;

        // Wait for inference job
        xQueueReceive(queue, &job, portMAX_DELAY);
        printf("Received inference job. job=%p, name=%s\n", job, job->name.c_str());

        bool status = inferenceProcess.runJob(*job);
        job->status = status;

        // Return inference job response
        xQueueSend(job->queue, &job, portMAX_DELAY);
    }

    vTaskDelete(NULL);
}

void inferenceJobTask(void *pvParameters) {
    QueueHandle_t inferenceProcessQueue = reinterpret_cast<QueueHandle_t>(pvParameters);

    // Create queue for response messages
    QueueHandle_t senderQueue = xQueueCreate(10, sizeof(xInferenceJob *));

    // Inference job
    DataPtr networkModel(networkModelData, sizeof(networkModelData));
    DataPtr input(inputData, sizeof(inputData));
    DataPtr expected(expectedData, sizeof(expectedData));

    xInferenceJob job;
    xInferenceJob *j = &job;
    job.name         = "mobilenet_v2";
    job.networkModel = networkModel;
    job.input.push_back(input);
    job.expectedOutput.push_back(expected);
    job.queue = senderQueue;

    // Send job
    printf("Sending inference job\n");
    xQueueSend(inferenceProcessQueue, &j, portMAX_DELAY);

    // Wait for response
    xQueueReceive(senderQueue, &j, portMAX_DELAY);
    printf("Received inference job response. status=%u\n", j->status);

    exit(j->status);
}

} // namespace

/* Keep the queue ouf of the stack sinde freertos resets it when the scheduler starts.*/
QueueHandle_t inferenceProcessQueue;

int main() {
    // Inference process
    inferenceProcessQueue = xQueueCreate(10, sizeof(xInferenceJob *));
    xTaskCreate(inferenceProcessTask, "inferenceProcess", 2 * 1024, inferenceProcessQueue, 1, nullptr);

    // Inference job task
    xTaskCreate(inferenceJobTask, "inferenceJob", 2 * 1024, inferenceProcessQueue, 2, nullptr);

    // Run the scheduler
    vTaskStartScheduler();

    return 0;
}
