/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * 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
 *
 *      http://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 "rsContext.h"

#include "rsThreadIO.h"

using namespace android;
using namespace android::renderscript;

ThreadIO::ThreadIO() : mUsingSocket(false) {
}

ThreadIO::~ThreadIO() {
}

void ThreadIO::init(bool useSocket) {
    mUsingSocket = useSocket;
    mToCore.init(16 * 1024);

    if (mUsingSocket) {
        mToClientSocket.init();
        mToCoreSocket.init();
    } else {
        mToClient.init(1024);
    }
}

void ThreadIO::shutdown() {
    //LOGE("shutdown 1");
    mToCore.shutdown();
    //LOGE("shutdown 2");
}

void ThreadIO::coreFlush() {
    //LOGE("coreFlush 1");
    if (mUsingSocket) {
    } else {
        mToCore.flush();
    }
    //LOGE("coreFlush 2");
}

void * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) {
    //LOGE("coreHeader %i %i", cmdID, dataLen);
    if (mUsingSocket) {
        CoreCmdHeader hdr;
        hdr.bytes = dataLen;
        hdr.cmdID = cmdID;
        mToCoreSocket.writeAsync(&hdr, sizeof(hdr));
    } else {
        mCoreCommandSize = dataLen;
        mCoreCommandID = cmdID;
        mCoreDataPtr = (uint8_t *)mToCore.reserve(dataLen);
        mCoreDataBasePtr = mCoreDataPtr;
    }
    //LOGE("coreHeader ret %p", mCoreDataPtr);
    return mCoreDataPtr;
}

void ThreadIO::coreData(const void *data, size_t dataLen) {
    //LOGE("coreData %p %i", data, dataLen);
    mToCoreSocket.writeAsync(data, dataLen);
    //LOGE("coreData ret %p", mCoreDataPtr);
}

void ThreadIO::coreCommit() {
    //LOGE("coreCommit %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize);
    if (mUsingSocket) {
    } else {
        rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize);
        mToCore.commit(mCoreCommandID, mCoreCommandSize);
    }
    //LOGE("coreCommit ret");
}

void ThreadIO::coreCommitSync() {
    //LOGE("coreCommitSync %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize);
    if (mUsingSocket) {
    } else {
        rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize);
        mToCore.commitSync(mCoreCommandID, mCoreCommandSize);
    }
    //LOGE("coreCommitSync ret");
}

void ThreadIO::clientShutdown() {
    //LOGE("coreShutdown 1");
    mToClient.shutdown();
    //LOGE("coreShutdown 2");
}

void ThreadIO::coreSetReturn(const void *data, size_t dataLen) {
    rsAssert(dataLen <= sizeof(mToCoreRet));
    memcpy(&mToCoreRet, data, dataLen);
}

void ThreadIO::coreGetReturn(void *data, size_t dataLen) {
    memcpy(data, &mToCoreRet, dataLen);
}


bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand, uint64_t timeToWait) {
    bool ret = false;
    uint64_t startTime = con->getTime();

    while (!mToCore.isEmpty() || waitForCommand) {
        uint32_t cmdID = 0;
        uint32_t cmdSize = 0;
        ret = true;
        if (con->props.mLogTimes) {
            con->timerSet(Context::RS_TIMER_IDLE);
        }

        uint64_t delay = 0;
        if (waitForCommand) {
            delay = timeToWait - (con->getTime() - startTime);
            if (delay > timeToWait) {
                delay = 0;
            }
        }
        const void * data = mToCore.get(&cmdID, &cmdSize, delay);
        if (!cmdSize) {
            // exception or timeout occurred.
            return false;
        }
        if (con->props.mLogTimes) {
            con->timerSet(Context::RS_TIMER_INTERNAL);
        }
        waitForCommand = false;
        //LOGV("playCoreCommands 3 %i %i", cmdID, cmdSize);

        if (cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) {
            rsAssert(cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
            LOGE("playCoreCommands error con %p, cmd %i", con, cmdID);
            mToCore.printDebugData();
        }
        gPlaybackFuncs[cmdID](con, data, cmdSize << 2);
        mToCore.next();
    }
    return ret;
}

RsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) {
    if (mUsingSocket) {
        mToClientSocket.read(&mLastClientHeader, sizeof(mLastClientHeader));
    } else {
        size_t bytesData = 0;
        const uint32_t *d = (const uint32_t *)mToClient.get(&mLastClientHeader.cmdID, (uint32_t*)&bytesData);
        if (bytesData >= sizeof(uint32_t)) {
            mLastClientHeader.userID = d[0];
            mLastClientHeader.bytes = bytesData - sizeof(uint32_t);
        } else {
            mLastClientHeader.userID = 0;
            mLastClientHeader.bytes = 0;
        }
    }
    receiveLen[0] = mLastClientHeader.bytes;
    usrID[0] = mLastClientHeader.userID;
    return (RsMessageToClientType)mLastClientHeader.cmdID;
}

RsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen,
                                uint32_t *usrID, size_t bufferLen) {
    receiveLen[0] = mLastClientHeader.bytes;
    usrID[0] = mLastClientHeader.userID;
    if (bufferLen < mLastClientHeader.bytes) {
        return RS_MESSAGE_TO_CLIENT_RESIZE;
    }
    if (mUsingSocket) {
        if (receiveLen[0]) {
            mToClientSocket.read(data, receiveLen[0]);
        }
        return (RsMessageToClientType)mLastClientHeader.cmdID;
    } else {
        uint32_t bytesData = 0;
        uint32_t commandID = 0;
        const uint32_t *d = (const uint32_t *)mToClient.get(&commandID, &bytesData);
        //LOGE("getMessageToClient 3    %i  %i", commandID, bytesData);
        //LOGE("getMessageToClient  %i %i", commandID, *subID);
        if (bufferLen >= receiveLen[0]) {
            memcpy(data, d+1, receiveLen[0]);
            mToClient.next();
            return (RsMessageToClientType)commandID;
        }
    }
    return RS_MESSAGE_TO_CLIENT_RESIZE;
}

bool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data,
                            size_t dataLen, bool waitForSpace) {
    ClientCmdHeader hdr;
    hdr.bytes = dataLen;
    hdr.cmdID = cmdID;
    hdr.userID = usrID;
    if (mUsingSocket) {
        mToClientSocket.writeAsync(&hdr, sizeof(hdr));
        if (dataLen) {
            mToClientSocket.writeAsync(data, dataLen);
        }
        return true;
    } else {
        if (!waitForSpace) {
            if (!mToClient.makeSpaceNonBlocking(dataLen + sizeof(hdr))) {
                // Not enough room, and not waiting.
                return false;
            }
        }

        //LOGE("sendMessageToClient 2");
        uint32_t *p = (uint32_t *)mToClient.reserve(dataLen + sizeof(usrID));
        p[0] = usrID;
        if (dataLen > 0) {
            memcpy(p+1, data, dataLen);
        }
        mToClient.commit(cmdID, dataLen + sizeof(usrID));
        //LOGE("sendMessageToClient 3");
        return true;
    }
    return false;
}

