/*
**
** 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/ICameraService.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)
{
}

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 frameId, camera_metadata* result) {
    ALOGV("%s: frameId = %d, result = %p", __FUNCTION__, frameId, 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(frameId, 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<CpuConsumer> cc = new CpuConsumer(heapCount, synchronousMode);
    cc->setName(String8("ProCamera::mCpuConsumer"));

    sp<Surface> stc = new Surface(
        cc->getProducerInterface());

    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
