/*
**
** Copyright (C) 2013, 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.
*/

//#define LOG_NDEBUG 0
#define LOG_TAG "ProCamera"
#include <utils/Log.h>
#include <utils/threads.h>
#include <utils/Mutex.h>

#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IMemory.h>

#include <camera/ProCamera.h>
#include <camera/IProCameraUser.h>
#include <camera/IProCameraCallbacks.h>

#include <gui/IGraphicBufferProducer.h>

#include <system/camera_metadata.h>

namespace android {

sp<ProCamera> ProCamera::connect(int cameraId)
{
    return CameraBaseT::connect(cameraId, String16(),
                                 ICameraService::USE_CALLING_UID);
}

ProCamera::ProCamera(int cameraId)
    : CameraBase(cameraId)
{
}

CameraTraits<ProCamera>::TCamConnectService CameraTraits<ProCamera>::fnConnectService =
        &ICameraService::connectPro;

ProCamera::~ProCamera()
{

}

/* IProCameraUser's implementation */

// callback from camera service
void ProCamera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
{
    return CameraBaseT::notifyCallback(msgType, ext1, ext2);
}

void ProCamera::onLockStatusChanged(
                                 IProCameraCallbacks::LockStatus newLockStatus)
{
    ALOGV("%s: newLockStatus = %d", __FUNCTION__, newLockStatus);

    sp<ProCameraListener> listener;
    {
        Mutex::Autolock _l(mLock);
        listener = mListener;
    }
    if (listener != NULL) {
        switch (newLockStatus) {
            case IProCameraCallbacks::LOCK_ACQUIRED:
                listener->onLockAcquired();
                break;
            case IProCameraCallbacks::LOCK_RELEASED:
                listener->onLockReleased();
                break;
            case IProCameraCallbacks::LOCK_STOLEN:
                listener->onLockStolen();
                break;
            default:
                ALOGE("%s: Unknown lock status: %d",
                      __FUNCTION__, newLockStatus);
        }
    }
}

void ProCamera::onResultReceived(int32_t requestId, camera_metadata* result) {
    ALOGV("%s: requestId = %d, result = %p", __FUNCTION__, requestId, result);

    sp<ProCameraListener> listener;
    {
        Mutex::Autolock _l(mLock);
        listener = mListener;
    }

    CameraMetadata tmp(result);

    // Unblock waitForFrame(id) callers
    {
        Mutex::Autolock al(mWaitMutex);
        mMetadataReady = true;
        mLatestMetadata = tmp; // make copy
        mWaitCondition.broadcast();
    }

    result = tmp.release();

    if (listener != NULL) {
        listener->onResultReceived(requestId, result);
    } else {
        free_camera_metadata(result);
    }

}

status_t ProCamera::exclusiveTryLock()
{
    sp <IProCameraUser> c = mCamera;
    if (c == 0) return NO_INIT;

    return c->exclusiveTryLock();
}
status_t ProCamera::exclusiveLock()
{
    sp <IProCameraUser> c = mCamera;
    if (c == 0) return NO_INIT;

    return c->exclusiveLock();
}
status_t ProCamera::exclusiveUnlock()
{
    sp <IProCameraUser> c = mCamera;
    if (c == 0) return NO_INIT;

    return c->exclusiveUnlock();
}
bool ProCamera::hasExclusiveLock()
{
    sp <IProCameraUser> c = mCamera;
    if (c == 0) return NO_INIT;

    return c->hasExclusiveLock();
}

// Note that the callee gets a copy of the metadata.
int ProCamera::submitRequest(const struct camera_metadata* metadata,
                             bool streaming)
{
    sp <IProCameraUser> c = mCamera;
    if (c == 0) return NO_INIT;

    return c->submitRequest(const_cast<struct camera_metadata*>(metadata),
                            streaming);
}

status_t ProCamera::cancelRequest(int requestId)
{
    sp <IProCameraUser> c = mCamera;
    if (c == 0) return NO_INIT;

    return c->cancelRequest(requestId);
}

status_t ProCamera::deleteStream(int streamId)
{
    sp <IProCameraUser> c = mCamera;
    if (c == 0) return NO_INIT;

    status_t s = c->deleteStream(streamId);

    mStreams.removeItem(streamId);

    return s;
}

status_t ProCamera::createStream(int width, int height, int format,
                                 const sp<Surface>& surface,
                                 /*out*/
                                 int* streamId)
{
    *streamId = -1;

    ALOGV("%s: createStreamW %dx%d (fmt=0x%x)", __FUNCTION__, width, height,
                                                                       format);

    if (surface == 0) {
        return BAD_VALUE;
    }

    return createStream(width, height, format,
                        surface->getIGraphicBufferProducer(),
                        streamId);
}

status_t ProCamera::createStream(int width, int height, int format,
                                 const sp<IGraphicBufferProducer>& bufferProducer,
                                 /*out*/
                                 int* streamId) {
    *streamId = -1;

    ALOGV("%s: createStreamT %dx%d (fmt=0x%x)", __FUNCTION__, width, height,
                                                                       format);

    if (bufferProducer == 0) {
        return BAD_VALUE;
    }

    sp <IProCameraUser> c = mCamera;
    status_t stat = c->createStream(width, height, format, bufferProducer,
                                    streamId);

    if (stat == OK) {
        StreamInfo s(*streamId);

        mStreams.add(*streamId, s);
    }

    return stat;
}

status_t ProCamera::createStreamCpu(int width, int height, int format,
                                    int heapCount,
                                    /*out*/
                                    sp<CpuConsumer>* cpuConsumer,
                                    int* streamId) {
    return createStreamCpu(width, height, format, heapCount,
                           /*synchronousMode*/true,
                           cpuConsumer, streamId);
}

status_t ProCamera::createStreamCpu(int width, int height, int format,
                                    int heapCount,
                                    bool synchronousMode,
                                    /*out*/
                                    sp<CpuConsumer>* cpuConsumer,
                                    int* streamId)
{
    ALOGV("%s: createStreamW %dx%d (fmt=0x%x)", __FUNCTION__, width, height,
                                                                        format);

    *cpuConsumer = NULL;

    sp <IProCameraUser> c = mCamera;
    if (c == 0) return NO_INIT;

    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&producer, &consumer);
    sp<CpuConsumer> cc = new CpuConsumer(consumer, heapCount
            /*, synchronousMode*/);
    cc->setName(String8("ProCamera::mCpuConsumer"));

    sp<Surface> stc = new Surface(producer);

    status_t s = createStream(width, height, format,
                              stc->getIGraphicBufferProducer(),
                              streamId);

    if (s != OK) {
        ALOGE("%s: Failure to create stream %dx%d (fmt=0x%x)", __FUNCTION__,
                    width, height, format);
        return s;
    }

    sp<ProFrameListener> frameAvailableListener =
        new ProFrameListener(this, *streamId);

    getStreamInfo(*streamId).cpuStream = true;
    getStreamInfo(*streamId).cpuConsumer = cc;
    getStreamInfo(*streamId).synchronousMode = synchronousMode;
    getStreamInfo(*streamId).stc = stc;
    // for lifetime management
    getStreamInfo(*streamId).frameAvailableListener = frameAvailableListener;

    cc->setFrameAvailableListener(frameAvailableListener);

    *cpuConsumer = cc;

    return s;
}

camera_metadata* ProCamera::getCameraInfo(int cameraId) {
    ALOGV("%s: cameraId = %d", __FUNCTION__, cameraId);

    sp <IProCameraUser> c = mCamera;
    if (c == 0) return NULL;

    camera_metadata* ptr = NULL;
    status_t status = c->getCameraInfo(cameraId, &ptr);

    if (status != OK) {
        ALOGE("%s: Failed to get camera info, error = %d", __FUNCTION__, status);
    }

    return ptr;
}

status_t ProCamera::createDefaultRequest(int templateId,
                                             camera_metadata** request) const {
    ALOGV("%s: templateId = %d", __FUNCTION__, templateId);

    sp <IProCameraUser> c = mCamera;
    if (c == 0) return NO_INIT;

    return c->createDefaultRequest(templateId, request);
}

void ProCamera::onFrameAvailable(int streamId) {
    ALOGV("%s: streamId = %d", __FUNCTION__, streamId);

    sp<ProCameraListener> listener = mListener;
    StreamInfo& stream = getStreamInfo(streamId);

    if (listener.get() != NULL) {
        listener->onFrameAvailable(streamId, stream.cpuConsumer);
    }

    // Unblock waitForFrame(id) callers
    {
        Mutex::Autolock al(mWaitMutex);
        getStreamInfo(streamId).frameReady++;
        mWaitCondition.broadcast();
    }
}

int ProCamera::waitForFrameBuffer(int streamId) {
    status_t stat = BAD_VALUE;
    Mutex::Autolock al(mWaitMutex);

    StreamInfo& si = getStreamInfo(streamId);

    if (si.frameReady > 0) {
        int numFrames = si.frameReady;
        si.frameReady = 0;
        return numFrames;
    } else {
        while (true) {
            stat = mWaitCondition.waitRelative(mWaitMutex,
                                                mWaitTimeout);
            if (stat != OK) {
                ALOGE("%s: Error while waiting for frame buffer: %d",
                    __FUNCTION__, stat);
                return stat;
            }

            if (si.frameReady > 0) {
                int numFrames = si.frameReady;
                si.frameReady = 0;
                return numFrames;
            }
            // else it was some other stream that got unblocked
        }
    }

    return stat;
}

int ProCamera::dropFrameBuffer(int streamId, int count) {
    StreamInfo& si = getStreamInfo(streamId);

    if (!si.cpuStream) {
        return BAD_VALUE;
    } else if (count < 0) {
        return BAD_VALUE;
    }

    if (!si.synchronousMode) {
        ALOGW("%s: No need to drop frames on asynchronous streams,"
              " as asynchronous mode only keeps 1 latest frame around.",
              __FUNCTION__);
        return BAD_VALUE;
    }

    int numDropped = 0;
    for (int i = 0; i < count; ++i) {
        CpuConsumer::LockedBuffer buffer;
        if (si.cpuConsumer->lockNextBuffer(&buffer) != OK) {
            break;
        }

        si.cpuConsumer->unlockBuffer(buffer);
        numDropped++;
    }

    return numDropped;
}

status_t ProCamera::waitForFrameMetadata() {
    status_t stat = BAD_VALUE;
    Mutex::Autolock al(mWaitMutex);

    if (mMetadataReady) {
        return OK;
    } else {
        while (true) {
            stat = mWaitCondition.waitRelative(mWaitMutex,
                                               mWaitTimeout);

            if (stat != OK) {
                ALOGE("%s: Error while waiting for metadata: %d",
                        __FUNCTION__, stat);
                return stat;
            }

            if (mMetadataReady) {
                mMetadataReady = false;
                return OK;
            }
            // else it was some other stream or metadata
        }
    }

    return stat;
}

CameraMetadata ProCamera::consumeFrameMetadata() {
    Mutex::Autolock al(mWaitMutex);

    // Destructive: Subsequent calls return empty metadatas
    CameraMetadata tmp = mLatestMetadata;
    mLatestMetadata.clear();

    return tmp;
}

ProCamera::StreamInfo& ProCamera::getStreamInfo(int streamId) {
    return mStreams.editValueFor(streamId);
}

}; // namespace android
