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

#ifndef MESSAGE_HANDLER_H
#define MESSAGE_HANDLER_H

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

#include "message_queue.hpp"
#include <ethosu_driver.h>
#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);

    friend void ::ethosu_inference_begin(struct ethosu_driver *drv, void *userArg);
    friend void ::ethosu_inference_end(struct ethosu_driver *drv, void *userArg);

    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_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 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
