/*
 * 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.
 */

#ifndef MESSAGE_HANDLER_H
#define MESSAGE_HANDLER_H

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

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

    QueueHandle_t inferenceQueue;
    QueueHandle_t outputQueue;
    InferenceProcess::InferenceProcess inference;
};

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
