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

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

#include <inttypes.h>
#include <stdio.h>

#include "ethosu_core_interface.h"
#include "message_handler.hpp"
#include "message_queue.hpp"
#include <mailbox.hpp>

#if defined(MHU_V2)
#include <mhu_v2.hpp>
#elif defined(MHU_JUNO)
#include <mhu_juno.hpp>
#else
#include <mhu_dummy.hpp>
#endif

/* Disable semihosting */
__asm(".global __use_no_semihosting\n\t");

using namespace EthosU;
using namespace MessageHandler;

/****************************************************************************
 * Defines
 ****************************************************************************/

// Nr. of tasks to process inferences with, reserves driver & runs inference (Normally 1 per NPU, but not a must)
#if defined(ETHOSU_NPU_COUNT)
constexpr size_t NUM_PARALLEL_TASKS = ETHOSU_NPU_COUNT;
#else
constexpr size_t NUM_PARALLEL_TASKS = 1;
#endif

// TensorArena static initialisation
constexpr size_t arenaSize = TENSOR_ARENA_SIZE / NUM_PARALLEL_TASKS;

__attribute__((section(".bss.tensor_arena"), aligned(16))) uint8_t tensorArena[NUM_PARALLEL_TASKS][arenaSize];

// Message queue from remote host
__attribute__((section("ethosu_core_in_queue"))) MessageQueue::Queue<1000> inputMessageQueue;

// Message queue to remote host
__attribute__((section("ethosu_core_out_queue"))) MessageQueue::Queue<1000> outputMessageQueue;

namespace {
// Queue used to pass inference requests to the inference runner task
QueueHandle_t inferenceQueue;

// Queue for message responses to the remote host
QueueHandle_t outputQueue;

// Mailbox driver
#ifdef MHU_V2
Mailbox::MHUv2 mailbox(MHU_TX_BASE_ADDRESS, MHU_RX_BASE_ADDRESS); // txBase, rxBase
#elif defined(MHU_JUNO)
Mailbox::MHUJuno mailbox(MHU_BASE_ADDRESS);
#else
Mailbox::MHUDummy mailbox;
#endif

} // namespace

/****************************************************************************
 * Mutex & Semaphore
 ****************************************************************************/

extern "C" {

void *ethosu_mutex_create(void) {
    return xSemaphoreCreateMutex();
}

void ethosu_mutex_lock(void *mutex) {
    SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(mutex);
    xSemaphoreTake(handle, portMAX_DELAY);
}

void ethosu_mutex_unlock(void *mutex) {
    SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(mutex);
    xSemaphoreGive(handle);
}

void *ethosu_semaphore_create(void) {
    return xSemaphoreCreateBinary();
}

void ethosu_semaphore_take(void *sem) {
    SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(sem);
    xSemaphoreTake(handle, portMAX_DELAY);
}

void ethosu_semaphore_give(void *sem) {
    SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(sem);
    xSemaphoreGiveFromISR(handle, NULL);
}
}

/****************************************************************************
 * Application
 ****************************************************************************/

namespace {

void mailboxIrqHandler() {
    mailbox.handleMessage();
}

void inferenceTask(void *pvParameters) {
    printf("Starting inference task\n");

    uint8_t *arena = reinterpret_cast<uint8_t *>(pvParameters);
    InferenceHandler process(arena, arenaSize, inferenceQueue, outputQueue);
    process.run();
}

void inputMessageTask(void *pvParameters) {
    (void)pvParameters;

    printf("Starting input message task\n");

    IncomingMessageHandler process(*inputMessageQueue.toQueue(), mailbox, inferenceQueue, outputQueue);
    process.run();
}

void outputMessageTask(void *pvParameters) {
    (void)pvParameters;

    printf("Starting output message task\n");

    MessageHandler::OutgoingMessageHandler process(*outputMessageQueue.toQueue(), mailbox, outputQueue);
    process.run();
}

} // namespace

// FreeRTOS application. NOTE: Additional tasks may require increased heap size.
int main() {
    BaseType_t ret;

#ifdef MHU_IRQ
    // Register mailbox interrupt handler
    NVIC_SetVector((IRQn_Type)MHU_IRQ, (uint32_t)&mailboxIrqHandler);
    NVIC_EnableIRQ((IRQn_Type)MHU_IRQ);
#endif

    if (!mailbox.verifyHardware()) {
        printf("Failed to verify mailbox hardware\n");
        return 1;
    }

    // Create message queues for inter process communication
    inferenceQueue = xQueueCreate(10, sizeof(ethosu_core_inference_req));
    outputQueue    = xQueueCreate(10, sizeof(OutputMessage));

    // Task for handling incoming messages from the remote host
    ret = xTaskCreate(inputMessageTask, "inputMessageTask", 512, nullptr, 2, nullptr);
    if (ret != pdPASS) {
        printf("Failed to create 'inputMessageTask'\n");
        return ret;
    }

    // Task for handling outgoing messages resposes to the remote host
    ret = xTaskCreate(outputMessageTask, "outputMessageTask", 512, nullptr, 2, nullptr);
    if (ret != pdPASS) {
        printf("Failed to create 'outputMessageTask'\n");
        return ret;
    }

    // One inference task for each NPU
    for (size_t n = 0; n < NUM_PARALLEL_TASKS; n++) {
        ret = xTaskCreate(inferenceTask, "inferenceTask", 8 * 1024, &tensorArena[n], 3, nullptr);
        if (ret != pdPASS) {
            printf("Failed to create 'inferenceTask%d'\n", n);
            return ret;
        }
    }

    // Start Scheduler
    vTaskStartScheduler();

    return 1;
}
