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

#ifndef MESSAGE_HANDLER_H
#define MESSAGE_HANDLER_H

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

#include "message_queue.hpp"
#if defined(ETHOSU)
#include <ethosu_driver.h>
#endif
#include <inference_process.hpp>
#include <mailbox.hpp>

#include <cstddef>
#include <cstdio>
#include <vector>

namespace MessageHandler {

class IncomingMessageHandler {
public:
    IncomingMessageHandler(EthosU::ethosu_core_queue &messageQueue,
                           Mailbox::Mailbox &mailbox,
                           QueueHandle_t inferenceQueue,
                           QueueHandle_t outputQueue);
    void run();

private:
    bool handleMessage();
    void queueErrorAndResetQueue(EthosU::ethosu_core_msg_err_type type, const char *message);
    static void handleIrq(void *userArg);

    MessageQueue::QueueImpl messageQueue;
    Mailbox::Mailbox &mailbox;
    QueueHandle_t inferenceQueue;
    QueueHandle_t outputQueue;
    SemaphoreHandle_t semaphore;
};

class InferenceHandler {
public:
    InferenceHandler(uint8_t *tensorArena, size_t arenaSize, QueueHandle_t inferenceQueue, QueueHandle_t outputQueue);

    void run();

private:
    void runInference(EthosU::ethosu_core_inference_req &req, EthosU::ethosu_core_inference_rsp &rsp);

    bool getInferenceJob(const EthosU::ethosu_core_inference_req &req, InferenceProcess::InferenceJob &job);

#if defined(ETHOSU)
    friend void ::ethosu_inference_begin(struct ethosu_driver *drv, void *userArg);
    friend void ::ethosu_inference_end(struct ethosu_driver *drv, void *userArg);
#endif

    QueueHandle_t inferenceQueue;
    QueueHandle_t outputQueue;
    InferenceProcess::InferenceProcess inference;
    EthosU::ethosu_core_inference_req *currentReq;
    EthosU::ethosu_core_inference_rsp *currentRsp;
};

struct OutputMessage {
    OutputMessage(EthosU::ethosu_core_msg_type _type = EthosU::ETHOSU_CORE_MSG_MAX) : type(_type) {}

    EthosU::ethosu_core_msg_type type;
    union {
        EthosU::ethosu_core_inference_rsp inference;
        EthosU::ethosu_core_network_info_rsp networkInfo;
        EthosU::ethosu_core_msg_err error;
        uint64_t userArg;
    } data;
};

class OutgoingMessageHandler {
public:
    OutgoingMessageHandler(EthosU::ethosu_core_queue &messageQueue,
                           Mailbox::Mailbox &mailbox,
                           QueueHandle_t outputQueue);
    void run();

private:
    void sendPong();
    void sendErrorRsp(EthosU::ethosu_core_msg_err &error);
    void sendVersionRsp();
    void sendCapabilitiesRsp(uint64_t userArg);
    void sendInferenceRsp(EthosU::ethosu_core_inference_rsp &inference);
    void sendNetworkInfoRsp(EthosU::ethosu_core_network_info_rsp &networkInfo);
    void readCapabilties(EthosU::ethosu_core_msg_capabilities_rsp &rsp);

    MessageQueue::QueueImpl messageQueue;
    Mailbox::Mailbox &mailbox;
    QueueHandle_t outputQueue;
    EthosU::ethosu_core_msg_capabilities_rsp capabilities;
};

} // namespace MessageHandler

#endif
