/*
 * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "IntelMetadataBuffer"
#include <utils/Log.h>

#include "IntelMetadataBuffer.h"
#include <string.h>
#include <stdio.h>

#ifdef INTEL_VIDEO_XPROC_SHARING
#include <binder/IServiceManager.h>
#include <binder/MemoryBase.h>
#include <binder/Parcel.h>
#include <utils/List.h>
#include <utils/threads.h>
#include <ui/GraphicBuffer.h>

//#define TEST

struct ShareMemMap {
    uint32_t sessionflag;
    int32_t value;
    int32_t value_backup;
    uint32_t type;
    sp<MemoryBase> membase;
    sp<GraphicBuffer> gbuffer;
};

List <ShareMemMap *> gShareMemMapList;
Mutex gShareMemMapListLock;

enum {
    SHARE_MEM = IBinder::FIRST_CALL_TRANSACTION,
    GET_MEM,
    CLEAR_MEM,
};

enum {
    ST_MEMBASE = 0,
    ST_GFX,
    ST_MAX,
};

#define REMOTE_PROVIDER 0x80000000
#define REMOTE_CONSUMER 0x40000000

static ShareMemMap* ReadMemObjFromBinder(const Parcel& data, uint32_t sessionflag, uint32_t value) {

    uint32_t type = data.readInt32();
    if (type >= ST_MAX)
        return NULL;

    ShareMemMap* map = new ShareMemMap;
    map->sessionflag = sessionflag;
    map->type = type;
    map->value_backup = value;
    map->membase = NULL;
    map->gbuffer= NULL;

//    LOGI("ReadMemObjFromBinder");

    if (type == ST_MEMBASE) /*offset, size, heap*/
    {
        ssize_t offset = data.readInt32();
        size_t size = data.readInt32();

        sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder());

        sp<MemoryBase> mem = new MemoryBase(heap, offset, size);
        if (mem == NULL)
        {
            delete map;
            return NULL;
        }

        map->value = (int32_t) ((int) ( mem->pointer() + 0x0FFF) & ~0x0FFF);
        map->membase = mem;

#ifdef TEST
        ALOGI("membase heapID:%d, pointer:%x data:%x, aligned value:%x", \
           heap->getHeapID(), mem->pointer(), *((int *)(mem->pointer())), map->value);
#endif

    }
    else if (type == ST_GFX) /*graphicbuffer*/
    {
        sp<GraphicBuffer> buffer = new GraphicBuffer();
        if (buffer == NULL)
        {
            delete map;
            return NULL;
        }
        data.read(*buffer);

        map->value = (uint32_t)buffer->handle;
        map->gbuffer = buffer;

#ifdef TEST
        void* usrptr[3];
        buffer->lock(GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_READ_OFTEN, &usrptr[0]);
        buffer->unlock();
        ALOGI("gfx handle:%x data:%x", (int32_t)buffer->handle, *((int *)usrptr[0]));
#endif
    }

    gShareMemMapListLock.lock();
    gShareMemMapList.push_back(map);
    gShareMemMapListLock.unlock();
    return map;
}

static status_t WriteMemObjToBinder(Parcel& data, ShareMemMap* smem) {

    if (smem->type >= ST_MAX)
        return BAD_VALUE;

//    LOGI("WriteMemObjToBinder");

    data.writeInt32(smem->type);

    if (smem->type == ST_MEMBASE) /*offset, size, heap*/
    {
        ssize_t offset;
        size_t size;
        sp<IMemoryHeap> heap = smem->membase->getMemory(&offset, &size);
        data.writeInt32(offset);
        data.writeInt32(size);
        data.writeStrongBinder(heap->asBinder());
#ifdef TEST
        ALOGI("membase heapID:%d pointer:%x data:%x", \
            heap->getHeapID(), smem->membase->pointer(), *((int *)(smem->membase->pointer())));
#endif
    }
    else if (smem->type == ST_GFX) /*graphicbuffer*/
        data.write(*(smem->gbuffer));

    return NO_ERROR;
}

static void ClearLocalMem(uint32_t sessionflag)
{
    List<ShareMemMap *>::iterator node;

    gShareMemMapListLock.lock();

    for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); )
    {
        if ((*node)->sessionflag == sessionflag) //remove all buffers belong to this session
        {
            (*node)->membase = NULL;
            (*node)->gbuffer = NULL;
            delete (*node);
            node = gShareMemMapList.erase(node);
        }
        else
            node ++;
    }

    gShareMemMapListLock.unlock();
}

static ShareMemMap* FindShareMem(uint32_t sessionflag, int32_t value, bool isBackup)
{
    List<ShareMemMap *>::iterator node;

    gShareMemMapListLock.lock();
    for(node = gShareMemMapList.begin(); node !=  gShareMemMapList.end(); node++)
    {
        if (isBackup)
        {
            if ((*node)->sessionflag == sessionflag && (*node)->value_backup == value)
            {
                gShareMemMapListLock.unlock();
                return (*node);
            }
        }
        else if ((*node)->sessionflag == sessionflag && (*node)->value == value)
        {
            gShareMemMapListLock.unlock();
            return (*node);
        }
    }
    gShareMemMapListLock.unlock();

    return NULL;
}

static ShareMemMap* PopShareMem(uint32_t sessionflag, int32_t value)
{
    List<ShareMemMap *>::iterator node;

    gShareMemMapListLock.lock();
    for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); node++)
    {
        if ((*node)->sessionflag == sessionflag && (*node)->value == value)
        {
            gShareMemMapList.erase(node);
            gShareMemMapListLock.unlock();
            return (*node);
        }
    }
    gShareMemMapListLock.unlock();

    return NULL;
}

static void PushShareMem(ShareMemMap* &smem)
{
    gShareMemMapListLock.lock();
    gShareMemMapList.push_back(smem);
    gShareMemMapListLock.unlock();
}

static sp<IBinder> GetIntelBufferSharingService() {

    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> binder = sm->checkService(String16("media.IntelBufferSharing"));

    if (binder == 0)
        LOGE("media.IntelBufferSharing service is not published");

    return binder;
}

IntelBufferSharingService* IntelBufferSharingService::gBufferService = NULL;

status_t IntelBufferSharingService::instantiate(){
    status_t ret = NO_ERROR;

    if (gBufferService == NULL) {
        gBufferService = new IntelBufferSharingService();
        ret = defaultServiceManager()->addService(String16("media.IntelBufferSharing"), gBufferService);
        LOGI("IntelBufferSharingService::instantiate() ret = %d\n", ret);
    }

    return ret;
}

status_t IntelBufferSharingService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {

    pid_t pid = data.readInt32();
    uint32_t sessionflag = data.readInt32();

    switch(code)
    {
        case SHARE_MEM:
        {

            if (pid == getpid()) //in same process, should not use binder
            {
                LOGE("onTransact in same process, wrong sessionflag?");
                return UNKNOWN_ERROR;
            }

            int32_t value = data.readInt32();

//            LOGI("onTransact SHARE_MEM value=%x", value);

            //different process
            ShareMemMap* map = ReadMemObjFromBinder(data, sessionflag, value);
            if (map == NULL)
                return UNKNOWN_ERROR;

            reply->writeInt32(map->value);

            return NO_ERROR;
        }
        case CLEAR_MEM:
        {
//            LOGI("onTransact CLEAR_MEM sessionflag=%x", sessionflag);

            if (pid == getpid()) //in same process, should not use binder
            {
                //same process, return same pointer in data
                LOGE("onTransact CLEAR_MEM in same process, wrong sessionflag?");
                return UNKNOWN_ERROR;
            }

            ClearLocalMem(sessionflag);
            return NO_ERROR;
        }
        case GET_MEM:
        {

            if (pid == getpid()) //in same process, should not use binder
            {
                LOGE("onTransact GET_MEM in same process, wrong sessionflag?");
                return UNKNOWN_ERROR;
            }

            int32_t value = data.readInt32();

//            LOGI("onTransact GET_MEM value=%x", value);

            ShareMemMap* smem = FindShareMem(sessionflag, value, false);
            if (smem && (NO_ERROR == WriteMemObjToBinder(*reply, smem)))
                return NO_ERROR;
            else
                LOGE("onTransact GET_MEM: Not find mem");

            return UNKNOWN_ERROR;
        }
        default:
            return BBinder::onTransact(code, data, reply, flags);

    }
    return NO_ERROR;
}
#endif

IntelMetadataBuffer::IntelMetadataBuffer()
{
    mType = MetadataBufferTypeCameraSource;
    mValue = 0;
    mInfo = NULL;
    mExtraValues = NULL;
    mExtraValues_Count = 0;
    mBytes = NULL;
    mSize = 0;
#ifdef INTEL_VIDEO_XPROC_SHARING
    mSessionFlag = 0;
#endif
}

IntelMetadataBuffer::IntelMetadataBuffer(MetadataBufferType type, int32_t value)
{
    mType = type;
    mValue = value;
    mInfo = NULL;
    mExtraValues = NULL;
    mExtraValues_Count = 0;
    mBytes = NULL;
    mSize = 0;
#ifdef INTEL_VIDEO_XPROC_SHARING
    mSessionFlag = 0;
#endif
}

IntelMetadataBuffer::~IntelMetadataBuffer()
{
    if (mInfo)
        delete mInfo;

    if (mExtraValues)
        delete[] mExtraValues;

    if (mBytes)
        delete[] mBytes;
}


IntelMetadataBuffer::IntelMetadataBuffer(const IntelMetadataBuffer& imb)
     :mType(imb.mType), mValue(imb.mValue), mInfo(NULL), mExtraValues(NULL),
      mExtraValues_Count(imb.mExtraValues_Count), mBytes(NULL), mSize(imb.mSize)
#ifdef INTEL_VIDEO_XPROC_SHARING
      ,mSessionFlag(imb.mSessionFlag)
#endif
{
    if (imb.mInfo)
        mInfo = new ValueInfo(*imb.mInfo);

    if (imb.mExtraValues)
    {
        mExtraValues = new int32_t[mExtraValues_Count];
        memcpy(mExtraValues, imb.mExtraValues, 4 * mExtraValues_Count);
    }

    if (imb.mBytes)
    {
        mBytes = new uint8_t[mSize];
        memcpy(mBytes, imb.mBytes, mSize);
    }
}

const IntelMetadataBuffer& IntelMetadataBuffer::operator=(const IntelMetadataBuffer& imb)
{
    mType = imb.mType;
    mValue = imb.mValue;
    mInfo = NULL;
    mExtraValues = NULL;
    mExtraValues_Count = imb.mExtraValues_Count;
    mBytes = NULL;
    mSize = imb.mSize;
#ifdef INTEL_VIDEO_XPROC_SHARING
    mSessionFlag = imb.mSessionFlag;
#endif

    if (imb.mInfo)
        mInfo = new ValueInfo(*imb.mInfo);

    if (imb.mExtraValues)
    {
        mExtraValues = new int32_t[mExtraValues_Count];
        memcpy(mExtraValues, imb.mExtraValues, 4 * mExtraValues_Count);
    }

    if (imb.mBytes)
    {
        mBytes = new uint8_t[mSize];
        memcpy(mBytes, imb.mBytes, mSize);
    }

    return *this;
}

IMB_Result IntelMetadataBuffer::GetType(MetadataBufferType& type)
{
    type = mType;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::SetType(MetadataBufferType type)
{
    if (type < MetadataBufferTypeLast)
        mType = type;
    else
        return IMB_INVAL_PARAM;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::GetValue(int32_t& value)
{
    value = mValue;

#ifndef INTEL_VIDEO_XPROC_SHARING
    return IMB_SUCCESS;
#else
    if ((mSessionFlag & REMOTE_CONSUMER) == 0) //no sharing or is local consumer
        return IMB_SUCCESS;

    //try to find if it is already cached.
    ShareMemMap* smem = FindShareMem(mSessionFlag, mValue, true);
    if(smem)
    {
        value = smem->value;
        return IMB_SUCCESS;
    }

    //is remote provider and not find from cache, then pull from service
    sp<IBinder> binder = GetIntelBufferSharingService();
    if (binder == 0)
        return IMB_NO_SERVICE;

    //Detect IntelBufferSharingService, share mem to service
    Parcel data, reply;

    //send pid, sessionflag, and memtype
    pid_t pid = getpid();
    data.writeInt32(pid);
    data.writeInt32(mSessionFlag);
    data.writeInt32(mValue);

    //do transcation
    if (binder->transact(GET_MEM, data, &reply) != NO_ERROR)
        return IMB_SERVICE_FAIL;

    //get type/Mem OBJ
    smem = ReadMemObjFromBinder(reply, mSessionFlag, mValue);
    if (smem)
        value = smem->value;
    else
        return IMB_SERVICE_FAIL;

    return IMB_SUCCESS;
#endif
}

IMB_Result IntelMetadataBuffer::SetValue(int32_t value)
{
    mValue = value;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::GetValueInfo(ValueInfo* &info)
{
    info = mInfo;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::SetValueInfo(ValueInfo* info)
{
    if (info)
    {
        if (mInfo == NULL)
            mInfo = new ValueInfo;

        memcpy(mInfo, info, sizeof(ValueInfo));
    }
    else
        return IMB_INVAL_PARAM;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::GetExtraValues(int32_t* &values, uint32_t& num)
{
    values = mExtraValues;
    num = mExtraValues_Count;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::SetExtraValues(int32_t* values, uint32_t num)
{
    if (values && num > 0)
    {
        if (mExtraValues && mExtraValues_Count != num)
        {
            delete[] mExtraValues;
            mExtraValues = NULL;
        }

        if (mExtraValues == NULL)
            mExtraValues = new int32_t[num];

        memcpy(mExtraValues, values, sizeof(int32_t) * num);
        mExtraValues_Count = num;
    }
    else
        return IMB_INVAL_PARAM;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::UnSerialize(uint8_t* data, uint32_t size)
{
    if (!data || size == 0)
        return IMB_INVAL_PARAM;

    MetadataBufferType type;
    int32_t value;
    uint32_t extrasize = size - 8;
    ValueInfo* info = NULL;
    int32_t* ExtraValues = NULL;
    uint32_t ExtraValues_Count = 0;

    memcpy(&type, data, 4);
    data += 4;
    memcpy(&value, data, 4);
    data += 4;

    switch (type)
    {
        case MetadataBufferTypeCameraSource:
        case MetadataBufferTypeEncoder:
        case MetadataBufferTypeUser:
        {
            if (extrasize >0 && extrasize < sizeof(ValueInfo))
                return IMB_INVAL_BUFFER;

            if (extrasize > sizeof(ValueInfo)) //has extravalues
            {
                if ( (extrasize - sizeof(ValueInfo)) % 4 != 0 )
                    return IMB_INVAL_BUFFER;
                ExtraValues_Count = (extrasize - sizeof(ValueInfo)) / 4;
            }

            if (extrasize > 0)
            {
                info = new ValueInfo;
                memcpy(info, data, sizeof(ValueInfo));
                data += sizeof(ValueInfo);
            }

            if (ExtraValues_Count > 0)
            {
                ExtraValues = new int32_t[ExtraValues_Count];
                memcpy(ExtraValues, data, ExtraValues_Count * 4);
            }

            break;
        }
        case MetadataBufferTypeGrallocSource:
            if (extrasize > 0)
                return IMB_INVAL_BUFFER;

            break;
        default:
            return IMB_INVAL_BUFFER;
    }

    //store data
    mType = type;
    mValue = value;
    if (mInfo)
        delete mInfo;
    mInfo = info;
    if (mExtraValues)
        delete[] mExtraValues;
    mExtraValues = ExtraValues;
    mExtraValues_Count = ExtraValues_Count;
#ifdef INTEL_VIDEO_XPROC_SHARING
    if (mInfo != NULL)
        mSessionFlag = mInfo->sessionFlag;
#endif
    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::Serialize(uint8_t* &data, uint32_t& size)
{
    if (mBytes == NULL)
    {
        if (mType == MetadataBufferTypeGrallocSource && mInfo)
            return IMB_INVAL_PARAM;

        //assemble bytes according members
        mSize = 8;
        if (mInfo)
        {
            mSize += sizeof(ValueInfo);
            if (mExtraValues)
                mSize += 4 * mExtraValues_Count;
        }

        mBytes = new uint8_t[mSize];
        uint8_t *ptr = mBytes;
        memcpy(ptr, &mType, 4);
        ptr += 4;
        memcpy(ptr, &mValue, 4);
        ptr += 4;

        if (mInfo)
        {
        #ifdef INTEL_VIDEO_XPROC_SHARING
            mInfo->sessionFlag = mSessionFlag;
        #endif
            memcpy(ptr, mInfo, sizeof(ValueInfo));
            ptr += sizeof(ValueInfo);

            if (mExtraValues)
                memcpy(ptr, mExtraValues, mExtraValues_Count * 4);
        }
    }

    data = mBytes;
    size = mSize;

    return IMB_SUCCESS;
}

uint32_t IntelMetadataBuffer::GetMaxBufferSize()
{
    return 256;
}

#ifdef INTEL_VIDEO_XPROC_SHARING
IMB_Result IntelMetadataBuffer::GetSessionFlag(uint32_t& sessionflag)
{
    sessionflag = mSessionFlag;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::SetSessionFlag(uint32_t sessionflag)
{
    mSessionFlag = sessionflag;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::ShareValue(sp<MemoryBase> mem)
{
    mValue = (int32_t)((int) ( mem->pointer() + 0x0FFF) & ~0x0FFF);

    if (mSessionFlag == 0) //no sharing
        return IMB_SUCCESS;

    if (mSessionFlag & REMOTE_PROVIDER) //is remote provider
    {
        sp<IBinder> binder = GetIntelBufferSharingService();
        if (binder == 0)
            return IMB_NO_SERVICE;

        //Detect IntelBufferSharingService, share mem to service
        Parcel data, reply;

        //send pid, sessionflag, and value
        pid_t pid = getpid();
        data.writeInt32(pid);
        data.writeInt32(mSessionFlag);
        data.writeInt32(mValue);

        //send type/obj (offset/size/MemHeap)
        ShareMemMap smem;
        smem.membase = mem;
        smem.type = ST_MEMBASE;
        if (WriteMemObjToBinder(data, &smem) != NO_ERROR)
            return IMB_SERVICE_FAIL;

        //do transcation
        if (binder->transact(SHARE_MEM, data, &reply) != NO_ERROR)
            return IMB_SERVICE_FAIL;

        //set new value gotten from peer
        mValue = reply.readInt32();
//        LOGI("ShareValue(membase) Get reply from sevice, new value:%x\n", mValue);
    }
    else  //is local provider , direct access list
    {
        ShareMemMap* smem = new ShareMemMap;
        smem->sessionflag = mSessionFlag;
        smem->value = mValue;
        smem->value_backup = mValue;
        smem->type = ST_MEMBASE;
        smem->membase = mem;
        smem->gbuffer = NULL;
        PushShareMem(smem);
    }

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::ShareValue(sp<GraphicBuffer> gbuffer)
{
    mValue = (int32_t)gbuffer->handle;

    if (mSessionFlag == 0) //no sharing
        return IMB_SUCCESS;

    if (mSessionFlag & REMOTE_PROVIDER == 0) //is remote provider
    {
        sp<IBinder> binder = GetIntelBufferSharingService();
        if (binder == 0)
            return IMB_NO_SERVICE;

        Parcel data, reply;

        //send pid, sessionflag, and memtype
        pid_t pid = getpid();
        data.writeInt32(pid);
        data.writeInt32(mSessionFlag);
        data.writeInt32(mValue);

        //send value/graphicbuffer obj
        ShareMemMap smem;
        smem.gbuffer = gbuffer;
        smem.type = ST_GFX;
        if (WriteMemObjToBinder(data, &smem) != NO_ERROR)
            return IMB_SERVICE_FAIL;

        //do transcation
        if (binder->transact(SHARE_MEM, data, &reply) != NO_ERROR)
            return IMB_SERVICE_FAIL;

        //set new value gotten from peer
        mValue = reply.readInt32();
//        LOGI("ShareValue(gfx) Get reply from sevice, new value:%x\n", mValue);
    }
    else //is local provider, direct access list
    {
        ShareMemMap* smem = new ShareMemMap;
        smem->sessionflag = mSessionFlag;
        smem->value = mValue;
        smem->value_backup = mValue;
        smem->type = ST_GFX;
        smem->membase = NULL;
        smem->gbuffer = gbuffer;
        PushShareMem(smem);
    }

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::ClearContext(uint32_t sessionflag, bool isProvider)
{
    if (sessionflag == 0) //no sharing
        return IMB_SUCCESS;

    //clear local firstly
    ClearLocalMem(sessionflag);

    //clear mem on service if it is remote user
    if ((isProvider && (sessionflag & REMOTE_PROVIDER)) || (!isProvider && (sessionflag & REMOTE_CONSUMER)))
    {
//        LOGI("CLEAR_MEM sessionflag=%x", sessionflag);

        sp<IBinder> binder = GetIntelBufferSharingService();
        if (binder == 0)
            return IMB_NO_SERVICE;

        //Detect IntelBufferSharingService, unshare mem from service
        Parcel data, reply;

        //send pid and sessionflag
        pid_t pid = getpid();
        data.writeInt32(pid);
        data.writeInt32(sessionflag);

        if (binder->transact(CLEAR_MEM, data, &reply) != NO_ERROR)
            return IMB_SERVICE_FAIL;
    }

    return IMB_SUCCESS;
}

uint32_t IntelMetadataBuffer::MakeSessionFlag(bool romoteProvider, bool remoteConsumer, uint16_t sindex)
{
    uint32_t sessionflag = 0;

    if (romoteProvider)
        sessionflag |= REMOTE_PROVIDER;

    if (remoteConsumer)
        sessionflag |= REMOTE_CONSUMER;

    return sessionflag + sindex;
}
#endif
