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

#include <cstddef>
#include <cstdio>

namespace MessageProcess {

QueueImpl::QueueImpl(ethosu_core_queue &queue) : queue(queue) {}

bool QueueImpl::empty() const {
    return queue.header.read == queue.header.write;
}

size_t QueueImpl::available() const {
    size_t avail = queue.header.write - queue.header.read;

    if (queue.header.read > queue.header.write) {
        avail += queue.header.size;
    }

    return avail;
}

size_t QueueImpl::capacity() const {
    return queue.header.size - available();
}

bool QueueImpl::read(uint8_t *dst, uint32_t length) {
    const uint8_t *end = dst + length;
    uint32_t rpos      = queue.header.read;

    if (length > available()) {
        return false;
    }

    while (dst < end) {
        *dst++ = queue.data[rpos];
        rpos   = (rpos + 1) % queue.header.size;
    }

    queue.header.read = rpos;

#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
    SCB_CleanDCache();
#endif

    return true;
}

bool QueueImpl::write(const Vec *vec, size_t length) {
    size_t total = 0;

    for (size_t i = 0; i < length; i++) {
        total += vec[i].length;
    }

    if (total > capacity()) {
        return false;
    }

    uint32_t wpos = queue.header.write;

    for (size_t i = 0; i < length; i++) {
        const uint8_t *src = reinterpret_cast<const uint8_t *>(vec[i].base);
        const uint8_t *end = src + vec[i].length;

        while (src < end) {
            queue.data[wpos] = *src++;
            wpos             = (wpos + 1) % queue.header.size;
        }
    }

    // Update the write position last
    queue.header.write = wpos;

#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
    SCB_CleanDCache();
#endif

    // TODO replace with mailbox driver APIs
    volatile uint32_t *set = reinterpret_cast<volatile uint32_t *>(0x41A00014);
    *set                   = 0x1;

    return true;
}

bool QueueImpl::write(const uint32_t type, const void *src, uint32_t length) {
    ethosu_core_msg msg = {type, length};
    Vec vec[2]          = {{&msg, sizeof(msg)}, {src, length}};

    return write(vec, 2);
}

MessageProcess::MessageProcess(ethosu_core_queue &in,
                               ethosu_core_queue &out,
                               InferenceProcess::InferenceProcess &inferenceProcess) :
    queueIn(in),
    queueOut(out), inferenceProcess(inferenceProcess) {}

void MessageProcess::run() {
    while (true) {
        // Handle all messages in queue
        while (handleMessage())
            ;

        // Wait for event
        __WFE();
    }
}

void MessageProcess::handleIrq() {
    __SEV();
}

bool MessageProcess::handleMessage() {
    ethosu_core_msg msg;
    union {
        ethosu_core_inference_req inferenceReq;
        uint8_t data[1000];
    } data;

#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
    SCB_InvalidateDCache();
#endif

    // Read msg header
    if (!queueIn.read(msg)) {
        return false;
    }

    printf("Message. type=%u, length=%u\n", msg.type, msg.length);

    // Read payload
    if (!queueIn.read(data.data, msg.length)) {
        printf("Failed to read payload.\n");
        return false;
    }

    switch (msg.type) {
    case ETHOSU_CORE_MSG_PING:
        printf("Ping\n");
        sendPong();
        break;
    case ETHOSU_CORE_MSG_INFERENCE_REQ: {
        std::memcpy(&data.inferenceReq, data.data, sizeof(data.data));

        ethosu_core_inference_req &req = data.inferenceReq;

        printf("InferenceReq. network={0x%x, %u}, ifm={0x%x, %u}, ofm={0x%x, %u}\n",
               req.network.ptr,
               req.network.size,
               req.ifm.ptr,
               req.ifm.size,
               req.ofm.ptr,
               req.ofm.size,
               req.user_arg);

        InferenceProcess::DataPtr networkModel(reinterpret_cast<void *>(req.network.ptr), req.network.size);
        InferenceProcess::DataPtr ifm(reinterpret_cast<void *>(req.ifm.ptr), req.ifm.size);
        InferenceProcess::DataPtr ofm(reinterpret_cast<void *>(req.ofm.ptr), req.ofm.size);
        InferenceProcess::DataPtr expectedOutput;
        InferenceProcess::InferenceJob job("job", networkModel, ifm, ofm, expectedOutput, -1);

        bool failed = inferenceProcess.runJob(job);

        sendInferenceRsp(data.inferenceReq.user_arg, job.output.size, failed);
        break;
    }
    default:
        break;
    }

    return true;
}

void MessageProcess::sendPong() {
    if (!queueOut.write(ETHOSU_CORE_MSG_PONG)) {
        printf("Failed to write pong.\n");
    }
}

void MessageProcess::sendInferenceRsp(uint64_t userArg, size_t ofmSize, bool failed) {
    ethosu_core_inference_rsp rsp;

    rsp.user_arg = userArg;
    rsp.ofm_size = ofmSize;
    rsp.status   = failed ? ETHOSU_CORE_STATUS_ERROR : ETHOSU_CORE_STATUS_OK;

    printf(
        "Sending inference response. userArg=0x%llx, ofm_size=%u, status=%u\n", rsp.user_arg, rsp.ofm_size, rsp.status);

    if (!queueOut.write(ETHOSU_CORE_MSG_INFERENCE_RSP, rsp)) {
        printf("Failed to write inference.\n");
    }
}
} // namespace MessageProcess
