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

#include "message_handler.hpp"

#include "cmsis_compiler.h"

#ifdef ETHOSU
#include <ethosu_driver.h>
#endif

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

#include <cstring>
#include <inttypes.h>

using namespace EthosU;
using namespace MessageQueue;

namespace MessageHandler {

/****************************************************************************
 * IncomingMessageHandler
 ****************************************************************************/

IncomingMessageHandler::IncomingMessageHandler(ethosu_core_queue &_messageQueue,
                                               Mailbox::Mailbox &_mailbox,
                                               QueueHandle_t _inferenceQueue,
                                               QueueHandle_t _outputQueue) :
    messageQueue(_messageQueue),
    mailbox(_mailbox), inferenceQueue(_inferenceQueue), outputQueue(_outputQueue) {
    mailbox.registerCallback(handleIrq, reinterpret_cast<void *>(this));
    semaphore = xSemaphoreCreateBinary();
}

void IncomingMessageHandler::run() {
    while (true) {
        // Wait for event
        xSemaphoreTake(semaphore, portMAX_DELAY);

        // Handle all messages in queue
        while (handleMessage()) {}
    }
}

void IncomingMessageHandler::handleIrq(void *userArg) {
    IncomingMessageHandler *_this = reinterpret_cast<IncomingMessageHandler *>(userArg);
    xSemaphoreGive(_this->semaphore);
}

void IncomingMessageHandler::queueErrorAndResetQueue(ethosu_core_msg_err_type type, const char *message) {
    OutputMessage msg(ETHOSU_CORE_MSG_ERR);
    msg.data.error.type = type;

    for (size_t i = 0; i < sizeof(msg.data.error.msg) && message[i]; i++) {
        msg.data.error.msg[i] = message[i];
    }

    xQueueSend(outputQueue, &msg, portMAX_DELAY);
    messageQueue.reset();
}

bool IncomingMessageHandler::handleMessage() {
    struct ethosu_core_msg msg;

    if (messageQueue.available() == 0) {
        return false;
    }

    // Read msg header
    // Only process a complete message header, else send error message
    // and reset queue
    if (!messageQueue.read(msg)) {
        queueErrorAndResetQueue(ETHOSU_CORE_MSG_ERR_INVALID_SIZE, "Failed to read a complete header");
        return false;
    }

    printf("Msg: header magic=%" PRIX32 ", type=%" PRIu32 ", length=%" PRIu32 "\n", msg.magic, msg.type, msg.length);

    if (msg.magic != ETHOSU_CORE_MSG_MAGIC) {
        printf("Msg: Invalid Magic\n");
        queueErrorAndResetQueue(ETHOSU_CORE_MSG_ERR_INVALID_MAGIC, "Invalid magic");
        return false;
    }

    switch (msg.type) {
    case ETHOSU_CORE_MSG_PING: {
        printf("Msg: Ping\n");

        OutputMessage message(ETHOSU_CORE_MSG_PONG);
        xQueueSend(outputQueue, &message, portMAX_DELAY);
        break;
    }
    case ETHOSU_CORE_MSG_ERR: {
        ethosu_core_msg_err error;

        if (!messageQueue.read(error)) {
            printf("ERROR: Msg: Failed to receive error message\n");
        } else {
            printf("Msg: Received an error response, type=%" PRIu32 ", msg=\"%s\"\n", error.type, error.msg);
        }

        messageQueue.reset();
        return false;
    }
    case ETHOSU_CORE_MSG_VERSION_REQ: {
        printf("Msg: Version request\n");

        OutputMessage message(ETHOSU_CORE_MSG_VERSION_RSP);
        xQueueSend(outputQueue, &message, portMAX_DELAY);
        break;
    }
    case ETHOSU_CORE_MSG_CAPABILITIES_REQ: {
        ethosu_core_capabilities_req capabilities;

        if (!messageQueue.read(capabilities)) {
            queueErrorAndResetQueue(ETHOSU_CORE_MSG_ERR_INVALID_PAYLOAD, "CapabilitiesReq. Failed to read payload");
            break;
        }

        printf("Msg: Capabilities request.user_arg=0x%" PRIx64 "\n", capabilities.user_arg);

        OutputMessage message(ETHOSU_CORE_MSG_CAPABILITIES_RSP);
        message.data.userArg = capabilities.user_arg;
        xQueueSend(outputQueue, &message, portMAX_DELAY);
        break;
    }
    case ETHOSU_CORE_MSG_INFERENCE_REQ: {
        ethosu_core_inference_req inference;

        if (!messageQueue.read(inference)) {
            queueErrorAndResetQueue(ETHOSU_CORE_MSG_ERR_INVALID_PAYLOAD, "InferenceReq. Failed to read payload");
            break;
        }

        printf("Msg: InferenceReq. user_arg=0x%" PRIx64 ", network={0x%" PRIx32 ", %" PRIu32 "}\n",
               inference.user_arg,
               inference.network.ptr,
               inference.network.size);

        printf(", ifm_count=%" PRIu32 ", ifm=[", inference.ifm_count);
        for (uint32_t i = 0; i < inference.ifm_count; ++i) {
            if (i > 0) {
                printf(", ");
            }

            printf("{0x%" PRIx32 ", %" PRIu32 "}", inference.ifm[i].ptr, inference.ifm[i].size);
        }
        printf("]");

        printf(", ofm_count=%" PRIu32 ", ofm=[", inference.ofm_count);
        for (uint32_t i = 0; i < inference.ofm_count; ++i) {
            if (i > 0) {
                printf(", ");
            }

            printf("{0x%" PRIx32 ", %" PRIu32 "}", inference.ofm[i].ptr, inference.ofm[i].size);
        }
        printf("]\n");

        xQueueSend(inferenceQueue, &inference, portMAX_DELAY);
        break;
    }
    default: {
        char errMsg[128];

        snprintf(&errMsg[0],
                 sizeof(errMsg),
                 "Msg: Unknown type: %" PRIu32 " with payload length %" PRIu32 " bytes\n",
                 msg.type,
                 msg.length);

        queueErrorAndResetQueue(ETHOSU_CORE_MSG_ERR_UNSUPPORTED_TYPE, errMsg);

        return false;
    }
    }

    return true;
}

/****************************************************************************
 * InferenceHandler
 ****************************************************************************/

InferenceHandler::InferenceHandler(uint8_t *tensorArena,
                                   size_t arenaSize,
                                   QueueHandle_t _inferenceQueue,
                                   QueueHandle_t _outputQueue) :
    inferenceQueue(_inferenceQueue),
    outputQueue(_outputQueue), inference(tensorArena, arenaSize) {}

void InferenceHandler::run() {
    while (true) {
        ethosu_core_inference_req req;

        if (pdTRUE != xQueueReceive(inferenceQueue, &req, portMAX_DELAY)) {
            continue;
        }

        OutputMessage msg(ETHOSU_CORE_MSG_INFERENCE_RSP);
        runInference(req, msg.data.inference);

        xQueueSend(outputQueue, &msg, portMAX_DELAY);
    }
}

void InferenceHandler::runInference(ethosu_core_inference_req &req, ethosu_core_inference_rsp &rsp) {
    /*
     * Setup inference job
     */

    InferenceProcess::DataPtr networkModel(reinterpret_cast<void *>(req.network.ptr), req.network.size);

    std::vector<InferenceProcess::DataPtr> ifm;
    for (uint32_t i = 0; i < req.ifm_count; ++i) {
        ifm.push_back(InferenceProcess::DataPtr(reinterpret_cast<void *>(req.ifm[i].ptr), req.ifm[i].size));
    }

    std::vector<InferenceProcess::DataPtr> ofm;
    for (uint32_t i = 0; i < req.ofm_count; ++i) {
        ofm.push_back(InferenceProcess::DataPtr(reinterpret_cast<void *>(req.ofm[i].ptr), req.ofm[i].size));
    }

    std::vector<InferenceProcess::DataPtr> expectedOutput;

    std::vector<uint8_t> pmuEventConfig(ETHOSU_CORE_PMU_MAX);
    for (uint32_t i = 0; i < ETHOSU_CORE_PMU_MAX; i++) {
        pmuEventConfig[i] = req.pmu_event_config[i];
    }

    InferenceProcess::InferenceJob job(
        "job", networkModel, ifm, ofm, expectedOutput, -1, pmuEventConfig, req.pmu_cycle_counter_enable);

    /*
     * Run inference
     */

    job.invalidate();
    bool failed = inference.runJob(job);
    job.clean();

    /*
     * Send inference response
     */

    rsp.user_arg  = req.user_arg;
    rsp.ofm_count = job.output.size();
    rsp.status    = failed ? ETHOSU_CORE_STATUS_ERROR : ETHOSU_CORE_STATUS_OK;

    for (size_t i = 0; i < job.output.size(); ++i) {
        rsp.ofm_size[i] = job.output[i].size;
    }

    for (size_t i = 0; i < job.pmuEventConfig.size(); i++) {
        rsp.pmu_event_config[i] = job.pmuEventConfig[i];
    }

    for (size_t i = 0; i < job.pmuEventCount.size(); i++) {
        rsp.pmu_event_count[i] = job.pmuEventCount[i];
    }

    rsp.pmu_cycle_counter_enable = job.pmuCycleCounterEnable;
    rsp.pmu_cycle_counter_count  = job.pmuCycleCounterCount;
}

/****************************************************************************
 * OutgoingMessageHandler
 ****************************************************************************/

OutgoingMessageHandler::OutgoingMessageHandler(ethosu_core_queue &_messageQueue,
                                               Mailbox::Mailbox &_mailbox,
                                               QueueHandle_t _outputQueue) :
    messageQueue(_messageQueue),
    mailbox(_mailbox), outputQueue(_outputQueue) {
    readCapabilties(capabilities);
}

void OutgoingMessageHandler::run() {
    while (true) {
        OutputMessage message;
        if (pdTRUE != xQueueReceive(outputQueue, &message, portMAX_DELAY)) {
            continue;
        }

        switch (message.type) {
        case ETHOSU_CORE_MSG_INFERENCE_RSP:
            sendInferenceRsp(message.data.inference);
            break;
        case ETHOSU_CORE_MSG_CAPABILITIES_RSP:
            sendCapabilitiesRsp(message.data.userArg);
            break;
        case ETHOSU_CORE_MSG_VERSION_RSP:
            sendVersionRsp();
            break;
        case ETHOSU_CORE_MSG_PONG:
            sendPong();
            break;
        case ETHOSU_CORE_MSG_ERR:
            sendErrorRsp(message.data.error);
            break;
        default:
            printf("Dropping unknown outcome of type %d\n", message.type);
            break;
        }
    }
}

void OutgoingMessageHandler::sendPong() {
    if (!messageQueue.write(ETHOSU_CORE_MSG_PONG)) {
        printf("ERROR: Msg: Failed to write pong response. No mailbox message sent\n");
    } else {
        mailbox.sendMessage();
    }
}

void OutgoingMessageHandler::sendVersionRsp() {
    ethosu_core_msg_version version = {
        ETHOSU_CORE_MSG_VERSION_MAJOR,
        ETHOSU_CORE_MSG_VERSION_MINOR,
        ETHOSU_CORE_MSG_VERSION_PATCH,
        0,
    };

    if (!messageQueue.write(ETHOSU_CORE_MSG_VERSION_RSP, version)) {
        printf("ERROR: Failed to write version response. No mailbox message sent\n");
    } else {
        mailbox.sendMessage();
    }
}

void OutgoingMessageHandler::sendCapabilitiesRsp(uint64_t userArg) {
    capabilities.user_arg = userArg;

    if (!messageQueue.write(ETHOSU_CORE_MSG_CAPABILITIES_RSP, capabilities)) {
        printf("ERROR: Failed to write capabilities response. No mailbox message sent\n");
    } else {
        mailbox.sendMessage();
    }
}

void OutgoingMessageHandler::sendInferenceRsp(ethosu_core_inference_rsp &inference) {
    if (!messageQueue.write(ETHOSU_CORE_MSG_INFERENCE_RSP, inference)) {
        printf("ERROR: Msg: Failed to write inference response. No mailbox message sent\n");
    } else {
        mailbox.sendMessage();
    }
}

void OutgoingMessageHandler::sendErrorRsp(ethosu_core_msg_err &error) {
    printf("ERROR: Msg: \"%s\"\n", error.msg);

    if (!messageQueue.write(ETHOSU_CORE_MSG_ERR, error)) {
        printf("ERROR: Msg: Failed to write error response. No mailbox message sent\n");
    } else {
        mailbox.sendMessage();
    }
}

void OutgoingMessageHandler::readCapabilties(ethosu_core_msg_capabilities_rsp &rsp) {
    rsp = {};

#ifdef ETHOSU
    struct ethosu_driver_version version;
    ethosu_get_driver_version(&version);

    struct ethosu_hw_info info;
    struct ethosu_driver *drv = ethosu_reserve_driver();
    ethosu_get_hw_info(drv, &info);
    ethosu_release_driver(drv);

    rsp.user_arg           = 0;
    rsp.version_status     = info.version.version_status;
    rsp.version_minor      = info.version.version_minor;
    rsp.version_major      = info.version.version_major;
    rsp.product_major      = info.version.product_major;
    rsp.arch_patch_rev     = info.version.arch_patch_rev;
    rsp.arch_minor_rev     = info.version.arch_minor_rev;
    rsp.arch_major_rev     = info.version.arch_major_rev;
    rsp.driver_patch_rev   = version.patch;
    rsp.driver_minor_rev   = version.minor;
    rsp.driver_major_rev   = version.major;
    rsp.macs_per_cc        = info.cfg.macs_per_cc;
    rsp.cmd_stream_version = info.cfg.cmd_stream_version;
    rsp.custom_dma         = info.cfg.custom_dma;
#endif
}

} // namespace MessageHandler
