/*
 * 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.
 */

#include <gtest/gtest.h>
#include <iostream>

#include <binder/IPCThreadState.h>
#include <utils/Thread.h>

#include "Camera.h"
#include "ProCamera.h"
#include <utils/Vector.h>
#include <utils/Mutex.h>
#include <utils/Condition.h>

#include <gui/SurfaceComposerClient.h>
#include <gui/Surface.h>

#include <system/camera_metadata.h>
#include <hardware/camera2.h> // for CAMERA2_TEMPLATE_PREVIEW only
#include <camera/CameraMetadata.h>

#include <camera/ICameraServiceListener.h>

namespace android {
namespace camera2 {
namespace tests {
namespace client {

#define CAMERA_ID 0
#define TEST_DEBUGGING 0

#define TEST_LISTENER_TIMEOUT 1000000000 // 1 second listener timeout
#define TEST_FORMAT HAL_PIXEL_FORMAT_Y16 //TODO: YUY2 instead

#define TEST_FORMAT_MAIN HAL_PIXEL_FORMAT_Y8
#define TEST_FORMAT_DEPTH HAL_PIXEL_FORMAT_Y16

// defaults for display "test"
#define TEST_DISPLAY_FORMAT HAL_PIXEL_FORMAT_Y8
#define TEST_DISPLAY_WIDTH 320
#define TEST_DISPLAY_HEIGHT 240

#define TEST_CPU_FRAME_COUNT 2
#define TEST_CPU_HEAP_COUNT 5

#define TEST_FRAME_PROCESSING_DELAY_US 200000 // 200 ms

#if TEST_DEBUGGING
#define dout std::cerr
#else
#define dout if (0) std::cerr
#endif

#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
#define ASSERT_OK(x) ASSERT_EQ(OK, (x))

class ProCameraTest;

struct ServiceListener : public BnCameraServiceListener {

    ServiceListener() :
        mLatestStatus(STATUS_UNKNOWN),
        mPrevStatus(STATUS_UNKNOWN)
    {
    }

    void onStatusChanged(Status status, int32_t cameraId) {
        dout << "On status changed: 0x" << std::hex
             << (unsigned int) status << " cameraId " << cameraId
             << std::endl;

        Mutex::Autolock al(mMutex);

        mLatestStatus = status;
        mCondition.broadcast();
    }

    status_t waitForStatusChange(Status& newStatus) {
        Mutex::Autolock al(mMutex);

        if (mLatestStatus != mPrevStatus) {
            newStatus = mLatestStatus;
            mPrevStatus = mLatestStatus;
            return OK;
        }

        status_t stat = mCondition.waitRelative(mMutex,
                                               TEST_LISTENER_TIMEOUT);

        if (stat == OK) {
            newStatus = mLatestStatus;
            mPrevStatus = mLatestStatus;
        }

        return stat;
    }

    Condition mCondition;
    Mutex mMutex;

    Status mLatestStatus;
    Status mPrevStatus;
};

enum ProEvent {
    UNKNOWN,
    ACQUIRED,
    RELEASED,
    STOLEN,
    FRAME_RECEIVED,
    RESULT_RECEIVED,
};

inline int ProEvent_Mask(ProEvent e) {
    return (1 << static_cast<int>(e));
}

typedef Vector<ProEvent> EventList;

class ProCameraTestThread : public Thread
{
public:
    ProCameraTestThread() {
    }

    virtual bool threadLoop() {
        mProc = ProcessState::self();
        mProc->startThreadPool();

        IPCThreadState *ptr = IPCThreadState::self();

        ptr->joinThreadPool();

        return false;
    }

    sp<ProcessState> mProc;
};

class ProCameraTestListener : public ProCameraListener {

public:
    static const int EVENT_MASK_ALL = 0xFFFFFFFF;

    ProCameraTestListener() {
        mEventMask = EVENT_MASK_ALL;
        mDropFrames = false;
    }

    status_t WaitForEvent() {
        Mutex::Autolock cal(mConditionMutex);

        {
            Mutex::Autolock al(mListenerMutex);

            if (mProEventList.size() > 0) {
                return OK;
            }
        }

        return mListenerCondition.waitRelative(mConditionMutex,
                                               TEST_LISTENER_TIMEOUT);
    }

    /* Read events into out. Existing queue is flushed */
    void ReadEvents(EventList& out) {
        Mutex::Autolock al(mListenerMutex);

        for (size_t i = 0; i < mProEventList.size(); ++i) {
            out.push(mProEventList[i]);
        }

        mProEventList.clear();
    }

    /**
      * Dequeue 1 event from the event queue.
      * Returns UNKNOWN if queue is empty
      */
    ProEvent ReadEvent() {
        Mutex::Autolock al(mListenerMutex);

        if (mProEventList.size() == 0) {
            return UNKNOWN;
        }

        ProEvent ev = mProEventList[0];
        mProEventList.removeAt(0);

        return ev;
    }

    void SetEventMask(int eventMask) {
        Mutex::Autolock al(mListenerMutex);
        mEventMask = eventMask;
    }

    // Automatically acquire/release frames as they are available
    void SetDropFrames(bool dropFrames) {
        Mutex::Autolock al(mListenerMutex);
        mDropFrames = dropFrames;
    }

private:
    void QueueEvent(ProEvent ev) {
        bool eventAdded = false;
        {
            Mutex::Autolock al(mListenerMutex);

            // Drop events not part of mask
            if (ProEvent_Mask(ev) & mEventMask) {
                mProEventList.push(ev);
                eventAdded = true;
            }
        }

        if (eventAdded) {
            mListenerCondition.broadcast();
        }
    }

protected:

    //////////////////////////////////////////////////
    ///////// ProCameraListener //////////////////////
    //////////////////////////////////////////////////


    // Lock has been acquired. Write operations now available.
    virtual void onLockAcquired() {
        QueueEvent(ACQUIRED);
    }
    // Lock has been released with exclusiveUnlock
    virtual void onLockReleased() {
        QueueEvent(RELEASED);
    }

    // Lock has been stolen by another client.
    virtual void onLockStolen() {
        QueueEvent(STOLEN);
    }

    // Lock free.
    virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) {

        dout << "Trigger notify: " << ext1 << " " << ext2
             << " " << ext3 << std::endl;
    }

    virtual void onFrameAvailable(int streamId,
                                  const sp<CpuConsumer>& consumer) {

        QueueEvent(FRAME_RECEIVED);

        Mutex::Autolock al(mListenerMutex);
        if (mDropFrames) {
            CpuConsumer::LockedBuffer buf;
            status_t ret;

            EXPECT_OK(ret);
            if (OK == (ret = consumer->lockNextBuffer(&buf))) {

                dout << "Frame received on streamId = " << streamId <<
                        ", dataPtr = " << (void*)buf.data <<
                        ", timestamp = " << buf.timestamp << std::endl;

                EXPECT_OK(consumer->unlockBuffer(buf));
            }
        } else {
            dout << "Frame received on streamId = " << streamId << std::endl;
        }
    }

    virtual void onResultReceived(int32_t frameId,
                                  camera_metadata* request) {
        dout << "Result received frameId = " << frameId
             << ", requestPtr = " << (void*)request << std::endl;
        QueueEvent(RESULT_RECEIVED);
        free_camera_metadata(request);
    }

    virtual void notify(int32_t msg, int32_t ext1, int32_t ext2) {
        dout << "Notify received: msg " << std::hex << msg
             << ", ext1: " << std::hex << ext1 << ", ext2: " << std::hex << ext2
             << std::endl;
    }

    Vector<ProEvent> mProEventList;
    Mutex             mListenerMutex;
    Mutex             mConditionMutex;
    Condition         mListenerCondition;
    int               mEventMask;
    bool              mDropFrames;
};

class ProCameraTest : public ::testing::Test {

public:
    ProCameraTest() {
        char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
        if (displaySecsEnv != NULL) {
            mDisplaySecs = atoi(displaySecsEnv);
            if (mDisplaySecs < 0) {
                mDisplaySecs = 0;
            }
        } else {
            mDisplaySecs = 0;
        }

        char* displayFmtEnv = getenv("TEST_DISPLAY_FORMAT");
        if (displayFmtEnv != NULL) {
            mDisplayFmt = FormatFromString(displayFmtEnv);
        } else {
            mDisplayFmt = TEST_DISPLAY_FORMAT;
        }

        char* displayWidthEnv = getenv("TEST_DISPLAY_WIDTH");
        if (displayWidthEnv != NULL) {
            mDisplayW = atoi(displayWidthEnv);
            if (mDisplayW < 0) {
                mDisplayW = 0;
            }
        } else {
            mDisplayW = TEST_DISPLAY_WIDTH;
        }

        char* displayHeightEnv = getenv("TEST_DISPLAY_HEIGHT");
        if (displayHeightEnv != NULL) {
            mDisplayH = atoi(displayHeightEnv);
            if (mDisplayH < 0) {
                mDisplayH = 0;
            }
        } else {
            mDisplayH = TEST_DISPLAY_HEIGHT;
        }
    }

    static void SetUpTestCase() {
        // Binder Thread Pool Initialization
        mTestThread = new ProCameraTestThread();
        mTestThread->run("ProCameraTestThread");
    }

    virtual void SetUp() {
        mCamera = ProCamera::connect(CAMERA_ID);
        ASSERT_NE((void*)NULL, mCamera.get());

        mListener = new ProCameraTestListener();
        mCamera->setListener(mListener);
    }

    virtual void TearDown() {
        ASSERT_NE((void*)NULL, mCamera.get());
        mCamera->disconnect();
    }

protected:
    sp<ProCamera> mCamera;
    sp<ProCameraTestListener> mListener;

    static sp<Thread> mTestThread;

    int mDisplaySecs;
    int mDisplayFmt;
    int mDisplayW;
    int mDisplayH;

    sp<SurfaceComposerClient> mComposerClient;
    sp<SurfaceControl> mSurfaceControl;

    sp<SurfaceComposerClient> mDepthComposerClient;
    sp<SurfaceControl> mDepthSurfaceControl;

    int getSurfaceWidth() {
        return 512;
    }
    int getSurfaceHeight() {
        return 512;
    }

    void createOnScreenSurface(sp<Surface>& surface) {
        mComposerClient = new SurfaceComposerClient;
        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());

        mSurfaceControl = mComposerClient->createSurface(
                String8("ProCameraTest StreamingImage Surface"),
                getSurfaceWidth(), getSurfaceHeight(),
                PIXEL_FORMAT_RGB_888, 0);

        mSurfaceControl->setPosition(0, 0);

        ASSERT_TRUE(mSurfaceControl != NULL);
        ASSERT_TRUE(mSurfaceControl->isValid());

        SurfaceComposerClient::openGlobalTransaction();
        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
        SurfaceComposerClient::closeGlobalTransaction();

        sp<ANativeWindow> window = mSurfaceControl->getSurface();
        surface = mSurfaceControl->getSurface();

        ASSERT_NE((void*)NULL, surface.get());
    }

    void createDepthOnScreenSurface(sp<Surface>& surface) {
        mDepthComposerClient = new SurfaceComposerClient;
        ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck());

        mDepthSurfaceControl = mDepthComposerClient->createSurface(
                String8("ProCameraTest StreamingImage Surface"),
                getSurfaceWidth(), getSurfaceHeight(),
                PIXEL_FORMAT_RGB_888, 0);

        mDepthSurfaceControl->setPosition(640, 0);

        ASSERT_TRUE(mDepthSurfaceControl != NULL);
        ASSERT_TRUE(mDepthSurfaceControl->isValid());

        SurfaceComposerClient::openGlobalTransaction();
        ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF));
        ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show());
        SurfaceComposerClient::closeGlobalTransaction();

        sp<ANativeWindow> window = mDepthSurfaceControl->getSurface();
        surface = mDepthSurfaceControl->getSurface();

        ASSERT_NE((void*)NULL, surface.get());
    }

    template <typename T>
    static bool ExistsItem(T needle, T* array, size_t count) {
        if (!array) {
            return false;
        }

        for (size_t i = 0; i < count; ++i) {
            if (array[i] == needle) {
                return true;
            }
        }
        return false;
    }


    static int FormatFromString(const char* str) {
        std::string s(str);

#define CMP_STR(x, y)                               \
        if (s == #x) return HAL_PIXEL_FORMAT_ ## y;
#define CMP_STR_SAME(x) CMP_STR(x, x)

        CMP_STR_SAME( Y16);
        CMP_STR_SAME( Y8);
        CMP_STR_SAME( YV12);
        CMP_STR(NV16, YCbCr_422_SP);
        CMP_STR(NV21, YCrCb_420_SP);
        CMP_STR(YUY2, YCbCr_422_I);
        CMP_STR(RAW,  RAW_SENSOR);
        CMP_STR(RGBA, RGBA_8888);

        std::cerr << "Unknown format string " << str << std::endl;
        return -1;

    }

    /**
     * Creating a streaming request for these output streams from a template,
     *  and submit it
     */
    void createSubmitRequestForStreams(uint8_t* streamIds, size_t count, int requestCount=-1) {

        ASSERT_NE((void*)NULL, streamIds);
        ASSERT_LT(0u, count);

        camera_metadata_t *requestTmp = NULL;
        EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
                                                /*out*/&requestTmp));
        ASSERT_NE((void*)NULL, requestTmp);
        CameraMetadata request(requestTmp);

        // set the output streams. default is empty

        uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
        request.update(tag, streamIds, count);

        requestTmp = request.release();

        if (requestCount < 0) {
            EXPECT_OK(mCamera->submitRequest(requestTmp, /*streaming*/true));
        } else {
            for (int i = 0; i < requestCount; ++i) {
                EXPECT_OK(mCamera->submitRequest(requestTmp,
                                                 /*streaming*/false));
            }
        }
        request.acquire(requestTmp);
    }
};

sp<Thread> ProCameraTest::mTestThread;

TEST_F(ProCameraTest, AvailableFormats) {
    if (HasFatalFailure()) {
        return;
    }

    CameraMetadata staticInfo = mCamera->getCameraInfo(CAMERA_ID);
    ASSERT_FALSE(staticInfo.isEmpty());

    uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS);
    EXPECT_TRUE(staticInfo.exists(tag));
    camera_metadata_entry_t entry = staticInfo.find(tag);

    EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YV12,
                                                  entry.data.i32, entry.count));
    EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP,
                                                  entry.data.i32, entry.count));
}

// test around exclusiveTryLock (immediate locking)
TEST_F(ProCameraTest, LockingImmediate) {

    if (HasFatalFailure()) {
        return;
    }

    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
                            ProEvent_Mask(STOLEN)   |
                            ProEvent_Mask(RELEASED));

    EXPECT_FALSE(mCamera->hasExclusiveLock());
    EXPECT_EQ(OK, mCamera->exclusiveTryLock());
    // at this point we definitely have the lock

    EXPECT_EQ(OK, mListener->WaitForEvent());
    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());

    EXPECT_TRUE(mCamera->hasExclusiveLock());
    EXPECT_EQ(OK, mCamera->exclusiveUnlock());

    EXPECT_EQ(OK, mListener->WaitForEvent());
    EXPECT_EQ(RELEASED, mListener->ReadEvent());

    EXPECT_FALSE(mCamera->hasExclusiveLock());
}

// test around exclusiveLock (locking at some future point in time)
TEST_F(ProCameraTest, LockingAsynchronous) {

    if (HasFatalFailure()) {
        return;
    }


    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
                            ProEvent_Mask(STOLEN)   |
                            ProEvent_Mask(RELEASED));

    // TODO: Add another procamera that has a lock here.
    // then we can be test that the lock wont immediately be acquired

    EXPECT_FALSE(mCamera->hasExclusiveLock());
    EXPECT_EQ(OK, mCamera->exclusiveTryLock());
    // at this point we definitely have the lock

    EXPECT_EQ(OK, mListener->WaitForEvent());
    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());

    EXPECT_TRUE(mCamera->hasExclusiveLock());
    EXPECT_EQ(OK, mCamera->exclusiveUnlock());

    EXPECT_EQ(OK, mListener->WaitForEvent());
    EXPECT_EQ(RELEASED, mListener->ReadEvent());

    EXPECT_FALSE(mCamera->hasExclusiveLock());
}

// Stream directly to the screen.
TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) {
    if (HasFatalFailure()) {
        return;
    }

    sp<Surface> surface;
    if (mDisplaySecs > 0) {
        createOnScreenSurface(/*out*/surface);
    }
    else {
        dout << "Skipping, will not render to screen" << std::endl;
        return;
    }

    int depthStreamId = -1;

    sp<ServiceListener> listener = new ServiceListener();
    EXPECT_OK(ProCamera::addServiceListener(listener));

    ServiceListener::Status currentStatus;

    // when subscribing a new listener,
    // we immediately get a callback to the current status
    while (listener->waitForStatusChange(/*out*/currentStatus) != OK);
    EXPECT_EQ(ServiceListener::STATUS_PRESENT, currentStatus);

    dout << "Will now stream and resume infinitely..." << std::endl;
    while (true) {

        if (currentStatus == ServiceListener::STATUS_PRESENT) {

            ASSERT_OK(mCamera->createStream(mDisplayW, mDisplayH, mDisplayFmt,
                                            surface,
                                            &depthStreamId));
            EXPECT_NE(-1, depthStreamId);

            EXPECT_OK(mCamera->exclusiveTryLock());

            uint8_t streams[] = { depthStreamId };
            ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(
                                                 streams,
                                                 /*count*/1));
        }

        ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;

        // TODO: maybe check for getch every once in a while?
        while (listener->waitForStatusChange(/*out*/stat) != OK);

        if (currentStatus != stat) {
            if (stat == ServiceListener::STATUS_PRESENT) {
                dout << "Reconnecting to camera" << std::endl;
                mCamera = ProCamera::connect(CAMERA_ID);
            } else if (stat == ServiceListener::STATUS_NOT_AVAILABLE) {
                dout << "Disconnecting from camera" << std::endl;
                mCamera->disconnect();
            } else if (stat == ServiceListener::STATUS_NOT_PRESENT) {
                dout << "Camera unplugged" << std::endl;
                mCamera = NULL;
            } else {
                dout << "Unknown status change "
                     << std::hex << stat << std::endl;
            }

            currentStatus = stat;
        }
    }

    EXPECT_OK(ProCamera::removeServiceListener(listener));
    EXPECT_OK(mCamera->deleteStream(depthStreamId));
    EXPECT_OK(mCamera->exclusiveUnlock());
}

// Stream directly to the screen.
TEST_F(ProCameraTest, DISABLED_StreamingImageDual) {
    if (HasFatalFailure()) {
        return;
    }
    sp<Surface> surface;
    sp<Surface> depthSurface;
    if (mDisplaySecs > 0) {
        createOnScreenSurface(/*out*/surface);
        createDepthOnScreenSurface(/*out*/depthSurface);
    }

    int streamId = -1;
    EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
              TEST_FORMAT_MAIN, surface, &streamId));
    EXPECT_NE(-1, streamId);

    int depthStreamId = -1;
    EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
              TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
    EXPECT_NE(-1, depthStreamId);

    EXPECT_OK(mCamera->exclusiveTryLock());
    /*
    */
    /* iterate in a loop submitting requests every frame.
     *  what kind of requests doesnt really matter, just whatever.
     */

    // it would probably be better to use CameraMetadata from camera service.
    camera_metadata_t *request = NULL;
    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
              /*out*/&request));
    EXPECT_NE((void*)NULL, request);

    /*FIXME: dont need this later, at which point the above should become an
             ASSERT_NE*/
    if(request == NULL) request = allocate_camera_metadata(10, 100);

    // set the output streams to just this stream ID

    // wow what a verbose API.
    uint8_t allStreams[] = { streamId, depthStreamId };
    // IMPORTANT. bad things will happen if its not a uint8.
    size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
    camera_metadata_entry_t entry;
    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
    int find = find_camera_metadata_entry(request, tag, &entry);
    if (find == -ENOENT) {
        if (add_camera_metadata_entry(request, tag, &allStreams,
                                      /*data_count*/streamCount) != OK) {
            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
            ASSERT_OK(append_camera_metadata(tmp, request));
            free_camera_metadata(request);
            request = tmp;

            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
                                                /*data_count*/streamCount));
        }
    } else {
        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
                  &allStreams, /*data_count*/streamCount, &entry));
    }

    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));

    dout << "will sleep now for " << mDisplaySecs << std::endl;
    sleep(mDisplaySecs);

    free_camera_metadata(request);

    for (int i = 0; i < streamCount; ++i) {
        EXPECT_OK(mCamera->deleteStream(allStreams[i]));
    }
    EXPECT_OK(mCamera->exclusiveUnlock());
}

TEST_F(ProCameraTest, CpuConsumerSingle) {
    if (HasFatalFailure()) {
        return;
    }

    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
                            ProEvent_Mask(STOLEN)   |
                            ProEvent_Mask(RELEASED) |
                            ProEvent_Mask(FRAME_RECEIVED));
    mListener->SetDropFrames(true);

    int streamId = -1;
    sp<CpuConsumer> consumer;
    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
                TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
    EXPECT_NE(-1, streamId);

    EXPECT_OK(mCamera->exclusiveTryLock());
    EXPECT_EQ(OK, mListener->WaitForEvent());
    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
    /* iterate in a loop submitting requests every frame.
     *  what kind of requests doesnt really matter, just whatever.
     */

    // it would probably be better to use CameraMetadata from camera service.
    camera_metadata_t *request = NULL;
    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
        /*out*/&request));
    EXPECT_NE((void*)NULL, request);

    /*FIXME: dont need this later, at which point the above should become an
      ASSERT_NE*/
    if(request == NULL) request = allocate_camera_metadata(10, 100);

    // set the output streams to just this stream ID

    uint8_t allStreams[] = { streamId };
    camera_metadata_entry_t entry;
    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
    int find = find_camera_metadata_entry(request, tag, &entry);
    if (find == -ENOENT) {
        if (add_camera_metadata_entry(request, tag, &allStreams,
                /*data_count*/1) != OK) {
            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
            ASSERT_OK(append_camera_metadata(tmp, request));
            free_camera_metadata(request);
            request = tmp;

            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
                /*data_count*/1));
        }
    } else {
        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
            &allStreams, /*data_count*/1, &entry));
    }

    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));

    // Consume a couple of frames
    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
        EXPECT_EQ(OK, mListener->WaitForEvent());
        EXPECT_EQ(FRAME_RECEIVED, mListener->ReadEvent());
    }

    // Done: clean up
    free_camera_metadata(request);
    EXPECT_OK(mCamera->deleteStream(streamId));
    EXPECT_OK(mCamera->exclusiveUnlock());
}

TEST_F(ProCameraTest, CpuConsumerDual) {
    if (HasFatalFailure()) {
        return;
    }

    mListener->SetEventMask(ProEvent_Mask(FRAME_RECEIVED));
    mListener->SetDropFrames(true);

    int streamId = -1;
    sp<CpuConsumer> consumer;
    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
                TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
    EXPECT_NE(-1, streamId);

    int depthStreamId = -1;
    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
            TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &depthStreamId));
    EXPECT_NE(-1, depthStreamId);

    EXPECT_OK(mCamera->exclusiveTryLock());
    /*
    */
    /* iterate in a loop submitting requests every frame.
     *  what kind of requests doesnt really matter, just whatever.
     */

    // it would probably be better to use CameraMetadata from camera service.
    camera_metadata_t *request = NULL;
    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
                                            /*out*/&request));
    EXPECT_NE((void*)NULL, request);

    if(request == NULL) request = allocate_camera_metadata(10, 100);

    // set the output streams to just this stream ID

    // wow what a verbose API.
    uint8_t allStreams[] = { streamId, depthStreamId };
    size_t streamCount = 2;
    camera_metadata_entry_t entry;
    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
    int find = find_camera_metadata_entry(request, tag, &entry);
    if (find == -ENOENT) {
        if (add_camera_metadata_entry(request, tag, &allStreams,
                                      /*data_count*/streamCount) != OK) {
            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
            ASSERT_OK(append_camera_metadata(tmp, request));
            free_camera_metadata(request);
            request = tmp;

            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
                                                   /*data_count*/streamCount));
        }
    } else {
        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
                              &allStreams, /*data_count*/streamCount, &entry));
    }

    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));

    // Consume a couple of frames
    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
        // stream id 1
        EXPECT_EQ(OK, mListener->WaitForEvent());
        EXPECT_EQ(FRAME_RECEIVED, mListener->ReadEvent());

        // stream id 2
        EXPECT_EQ(OK, mListener->WaitForEvent());
        EXPECT_EQ(FRAME_RECEIVED, mListener->ReadEvent());

        //TODO: events should be a struct with some data like the stream id
    }

    // Done: clean up
    free_camera_metadata(request);
    EXPECT_OK(mCamera->deleteStream(streamId));
    EXPECT_OK(mCamera->exclusiveUnlock());
}

TEST_F(ProCameraTest, ResultReceiver) {
    if (HasFatalFailure()) {
        return;
    }

    mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED));
    mListener->SetDropFrames(true);
    //FIXME: if this is run right after the previous test we get FRAME_RECEIVED
    // need to filter out events at read time

    int streamId = -1;
    sp<CpuConsumer> consumer;
    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
                TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
    EXPECT_NE(-1, streamId);

    EXPECT_OK(mCamera->exclusiveTryLock());
    /*
    */
    /* iterate in a loop submitting requests every frame.
     *  what kind of requests doesnt really matter, just whatever.
     */

    camera_metadata_t *request = NULL;
    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
                                            /*out*/&request));
    EXPECT_NE((void*)NULL, request);

    /*FIXME*/
    if(request == NULL) request = allocate_camera_metadata(10, 100);

    // set the output streams to just this stream ID

    uint8_t allStreams[] = { streamId };
    size_t streamCount = 1;
    camera_metadata_entry_t entry;
    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
    int find = find_camera_metadata_entry(request, tag, &entry);
    if (find == -ENOENT) {
        if (add_camera_metadata_entry(request, tag, &allStreams,
                                      /*data_count*/streamCount) != OK) {
            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
            ASSERT_OK(append_camera_metadata(tmp, request));
            free_camera_metadata(request);
            request = tmp;

            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
                                                /*data_count*/streamCount));
        }
    } else {
        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
                               &allStreams, /*data_count*/streamCount, &entry));
    }

    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));

    // Consume a couple of results
    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
        EXPECT_EQ(OK, mListener->WaitForEvent());
        EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent());
    }

    // Done: clean up
    free_camera_metadata(request);
    EXPECT_OK(mCamera->deleteStream(streamId));
    EXPECT_OK(mCamera->exclusiveUnlock());
}

// FIXME: This is racy and sometimes fails on waitForFrameMetadata
TEST_F(ProCameraTest, DISABLED_WaitForResult) {
    if (HasFatalFailure()) {
        return;
    }

    mListener->SetDropFrames(true);

    int streamId = -1;
    sp<CpuConsumer> consumer;
    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
                 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
    EXPECT_NE(-1, streamId);

    EXPECT_OK(mCamera->exclusiveTryLock());

    uint8_t streams[] = { streamId };
    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1));

    // Consume a couple of results
    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
        EXPECT_OK(mCamera->waitForFrameMetadata());
        CameraMetadata meta = mCamera->consumeFrameMetadata();
        EXPECT_FALSE(meta.isEmpty());
    }

    // Done: clean up
    EXPECT_OK(mCamera->deleteStream(streamId));
    EXPECT_OK(mCamera->exclusiveUnlock());
}

TEST_F(ProCameraTest, WaitForSingleStreamBuffer) {
    if (HasFatalFailure()) {
        return;
    }

    int streamId = -1;
    sp<CpuConsumer> consumer;
    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
    EXPECT_NE(-1, streamId);

    EXPECT_OK(mCamera->exclusiveTryLock());

    uint8_t streams[] = { streamId };
    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
                                            /*requests*/TEST_CPU_FRAME_COUNT));

    // Consume a couple of results
    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
        EXPECT_EQ(1, mCamera->waitForFrameBuffer(streamId));

        CpuConsumer::LockedBuffer buf;
        EXPECT_OK(consumer->lockNextBuffer(&buf));

        dout << "Buffer synchronously received on streamId = " << streamId <<
                ", dataPtr = " << (void*)buf.data <<
                ", timestamp = " << buf.timestamp << std::endl;

        EXPECT_OK(consumer->unlockBuffer(buf));
    }

    // Done: clean up
    EXPECT_OK(mCamera->deleteStream(streamId));
    EXPECT_OK(mCamera->exclusiveUnlock());
}

// FIXME: This is racy and sometimes fails on waitForFrameMetadata
TEST_F(ProCameraTest, DISABLED_WaitForDualStreamBuffer) {
    if (HasFatalFailure()) {
        return;
    }

    const int REQUEST_COUNT = TEST_CPU_FRAME_COUNT * 10;

    // 15 fps
    int streamId = -1;
    sp<CpuConsumer> consumer;
    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
                 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
    EXPECT_NE(-1, streamId);

    // 30 fps
    int depthStreamId = -1;
    sp<CpuConsumer> depthConsumer;
    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
       TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthConsumer, &depthStreamId));
    EXPECT_NE(-1, depthStreamId);

    EXPECT_OK(mCamera->exclusiveTryLock());

    uint8_t streams[] = { streamId, depthStreamId };
    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/2,
                                                    /*requests*/REQUEST_COUNT));

    int depthFrames = 0;
    int greyFrames = 0;

    // Consume two frames simultaneously. Unsynchronized by timestamps.
    for (int i = 0; i < REQUEST_COUNT; ++i) {

        // Exhaust event queue so it doesn't keep growing
        while (mListener->ReadEvent() != UNKNOWN);

        // Get the metadata
        EXPECT_OK(mCamera->waitForFrameMetadata());
        CameraMetadata meta = mCamera->consumeFrameMetadata();
        EXPECT_FALSE(meta.isEmpty());

        // Get the buffers

        EXPECT_EQ(1, mCamera->waitForFrameBuffer(depthStreamId));

        /**
          * Guaranteed to be able to consume the depth frame,
          * since we waited on it.
          */
        CpuConsumer::LockedBuffer depthBuffer;
        EXPECT_OK(depthConsumer->lockNextBuffer(&depthBuffer));

        dout << "Depth Buffer synchronously received on streamId = " <<
                streamId <<
                ", dataPtr = " << (void*)depthBuffer.data <<
                ", timestamp = " << depthBuffer.timestamp << std::endl;

        EXPECT_OK(depthConsumer->unlockBuffer(depthBuffer));

        depthFrames++;


        /** Consume Greyscale frames if there are any.
          * There may not be since it runs at half FPS */
        CpuConsumer::LockedBuffer greyBuffer;
        while (consumer->lockNextBuffer(&greyBuffer) == OK) {

            dout << "GRAY Buffer synchronously received on streamId = " <<
                streamId <<
                ", dataPtr = " << (void*)greyBuffer.data <<
                ", timestamp = " << greyBuffer.timestamp << std::endl;

            EXPECT_OK(consumer->unlockBuffer(greyBuffer));

            greyFrames++;
        }
    }

    dout << "Done, summary: depth frames " << std::dec << depthFrames
         << ", grey frames " << std::dec << greyFrames << std::endl;

    // Done: clean up
    EXPECT_OK(mCamera->deleteStream(streamId));
    EXPECT_OK(mCamera->exclusiveUnlock());
}

TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesSync) {
    if (HasFatalFailure()) {
        return;
    }

    const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;

    int streamId = -1;
    sp<CpuConsumer> consumer;
    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT,
                  /*synchronousMode*/true, &consumer, &streamId));
    EXPECT_NE(-1, streamId);

    EXPECT_OK(mCamera->exclusiveTryLock());

    uint8_t streams[] = { streamId };
    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
                                                     /*requests*/NUM_REQUESTS));

    // Consume a couple of results
    for (int i = 0; i < NUM_REQUESTS; ++i) {
        int numFrames;
        EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0);

        // Drop all but the newest framebuffer
        EXPECT_EQ(numFrames-1, mCamera->dropFrameBuffer(streamId, numFrames-1));

        dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;

        // Skip the counter ahead, don't try to consume these frames again
        i += numFrames-1;

        // "Consume" the buffer
        CpuConsumer::LockedBuffer buf;
        EXPECT_OK(consumer->lockNextBuffer(&buf));

        dout << "Buffer synchronously received on streamId = " << streamId <<
                ", dataPtr = " << (void*)buf.data <<
                ", timestamp = " << buf.timestamp << std::endl;

        // Process at 10fps, stream is at 15fps.
        // This means we will definitely fill up the buffer queue with
        // extra buffers and need to drop them.
        usleep(TEST_FRAME_PROCESSING_DELAY_US);

        EXPECT_OK(consumer->unlockBuffer(buf));
    }

    // Done: clean up
    EXPECT_OK(mCamera->deleteStream(streamId));
    EXPECT_OK(mCamera->exclusiveUnlock());
}

TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesAsync) {
    if (HasFatalFailure()) {
        return;
    }

    const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;
    const int CONSECUTIVE_FAILS_ASSUME_TIME_OUT = 5;

    int streamId = -1;
    sp<CpuConsumer> consumer;
    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT,
                  /*synchronousMode*/false, &consumer, &streamId));
    EXPECT_NE(-1, streamId);

    EXPECT_OK(mCamera->exclusiveTryLock());

    uint8_t streams[] = { streamId };
    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
                                                     /*requests*/NUM_REQUESTS));

    uint64_t lastFrameNumber = 0;
    int numFrames;

    // Consume a couple of results
    int i;
    for (i = 0; i < NUM_REQUESTS && lastFrameNumber < NUM_REQUESTS; ++i) {
        EXPECT_LT(0, (numFrames = mCamera->waitForFrameBuffer(streamId)));

        dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;

        // Skip the counter ahead, don't try to consume these frames again
        i += numFrames-1;

        // "Consume" the buffer
        CpuConsumer::LockedBuffer buf;

        EXPECT_EQ(OK, consumer->lockNextBuffer(&buf));

        lastFrameNumber = buf.frameNumber;

        dout << "Buffer asynchronously received on streamId = " << streamId <<
                ", dataPtr = " << (void*)buf.data <<
                ", timestamp = " << buf.timestamp <<
                ", framenumber = " << buf.frameNumber << std::endl;

        // Process at 10fps, stream is at 15fps.
        // This means we will definitely fill up the buffer queue with
        // extra buffers and need to drop them.
        usleep(TEST_FRAME_PROCESSING_DELAY_US);

        EXPECT_OK(consumer->unlockBuffer(buf));
    }

    dout << "Done after " << i << " iterations " << std::endl;

    // Done: clean up
    EXPECT_OK(mCamera->deleteStream(streamId));
    EXPECT_OK(mCamera->exclusiveUnlock());
}



//TODO: refactor into separate file
TEST_F(ProCameraTest, ServiceListenersSubscribe) {

    ASSERT_EQ(4u, sizeof(ServiceListener::Status));

    sp<ServiceListener> listener = new ServiceListener();

    EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
    EXPECT_OK(ProCamera::addServiceListener(listener));

    EXPECT_EQ(ALREADY_EXISTS, ProCamera::addServiceListener(listener));
    EXPECT_OK(ProCamera::removeServiceListener(listener));

    EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
}

//TODO: refactor into separate file
TEST_F(ProCameraTest, ServiceListenersFunctional) {

    sp<ServiceListener> listener = new ServiceListener();

    EXPECT_OK(ProCamera::addServiceListener(listener));

    sp<Camera> cam = Camera::connect(CAMERA_ID,
                                     /*clientPackageName*/String16(),
                                     -1);
    EXPECT_NE((void*)NULL, cam.get());

    ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
    EXPECT_OK(listener->waitForStatusChange(/*out*/stat));

    EXPECT_EQ(ServiceListener::STATUS_NOT_AVAILABLE, stat);

    if (cam.get()) {
        cam->disconnect();
    }

    EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
    EXPECT_EQ(ServiceListener::STATUS_PRESENT, stat);

    EXPECT_OK(ProCamera::removeServiceListener(listener));
}



}
}
}
}

