/*
 * Copyright (C) 2017 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 "CameraZSLTests"

#include <gtest/gtest.h>

#include <binder/ProcessState.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <camera/CameraParameters.h>
#include <camera/CameraMetadata.h>
#include <camera/Camera.h>
#include <camera/StringUtils.h>
#include <android/hardware/ICameraService.h>

using namespace android;
using namespace android::hardware;

class CameraZSLTests : public ::testing::Test,
    public ::android::hardware::BnCameraClient {
protected:

    CameraZSLTests() : numCameras(0), mPreviewBufferCount(0),
    mAutoFocusMessage(false), mSnapshotNotification(false) {}

    //Gtest interface
    void SetUp() override;
    void TearDown() override;

    //CameraClient interface
    void notifyCallback(int32_t msgType, int32_t, int32_t) override;
    void dataCallback(int32_t msgType, const sp<IMemory>&,
            camera_frame_metadata_t *) override;
    void dataCallbackTimestamp(nsecs_t, int32_t,
            const sp<IMemory>&) override {};
    void recordingFrameHandleCallbackTimestamp(nsecs_t,
            native_handle_t*) override {};
    void recordingFrameHandleCallbackTimestampBatch(
            const std::vector<nsecs_t>&,
            const std::vector<native_handle_t*>&) override {};

    status_t waitForPreviewStart();
    status_t waitForEvent(Mutex &mutex, Condition &condition, bool &flag);

    mutable Mutex mPreviewLock;
    mutable Condition mPreviewCondition;
    mutable Mutex mAutoFocusLock;
    mutable Condition mAutoFocusCondition;
    mutable Mutex mSnapshotLock;
    mutable Condition mSnapshotCondition;

    int32_t numCameras;
    size_t mPreviewBufferCount;
    sp<ICameraService> mCameraService;
    sp<SurfaceComposerClient> mComposerClient;
    bool mAutoFocusMessage;
    bool mSnapshotNotification;
    static const int32_t kPreviewThreshold  = 8;
    static const nsecs_t kPreviewTimeout    = 5000000000;  // 5 [s.]
    static const nsecs_t kEventTimeout      = 10000000000; // 10 [s.]
};

void CameraZSLTests::SetUp() {
    ::android::binder::Status rc;
    ProcessState::self()->startThreadPool();
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> binder = sm->getService(String16("media.camera"));
    mCameraService = interface_cast<ICameraService>(binder);
    rc = mCameraService->getNumberOfCameras(
            hardware::ICameraService::CAMERA_TYPE_ALL, &numCameras);
    EXPECT_TRUE(rc.isOk());

    mComposerClient = new SurfaceComposerClient;
    ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
}

void CameraZSLTests::TearDown() {
    mCameraService.clear();
    mComposerClient->dispose();
}

void CameraZSLTests::notifyCallback(int32_t msgType, int32_t,
        int32_t) {
    if (CAMERA_MSG_FOCUS == msgType) {
        Mutex::Autolock l(mAutoFocusLock);
        mAutoFocusMessage = true;
        mAutoFocusCondition.broadcast();
    } else {
        ALOGV("%s: msgType: %d", __FUNCTION__, msgType);
    }
};

void CameraZSLTests::dataCallback(int32_t msgType, const sp<IMemory>& /*data*/,
        camera_frame_metadata_t *) {

    switch (msgType) {
    case CAMERA_MSG_PREVIEW_FRAME: {
        Mutex::Autolock l(mPreviewLock);
        mPreviewBufferCount++;
        mPreviewCondition.broadcast();
        break;
    }
    case CAMERA_MSG_COMPRESSED_IMAGE: {
        Mutex::Autolock l(mSnapshotLock);
        mSnapshotNotification = true;
        //TODO: Add checks on incoming Jpeg
        mSnapshotCondition.broadcast();
        break;
    }
    default:
        ALOGV("%s: msgType: %d", __FUNCTION__, msgType);
    }
};

status_t CameraZSLTests::waitForPreviewStart() {
    status_t rc = NO_ERROR;
    Mutex::Autolock l(mPreviewLock);
    mPreviewBufferCount = 0;

    while (mPreviewBufferCount < kPreviewThreshold) {
        rc = mPreviewCondition.waitRelative(mPreviewLock,
                kPreviewTimeout);
        if (NO_ERROR != rc) {
            break;
        }
    }

    return rc;
}

status_t CameraZSLTests::waitForEvent(Mutex &mutex,
        Condition &condition, bool &flag) {
    status_t rc = NO_ERROR;
    Mutex::Autolock l(mutex);
    flag = false;

    while (!flag) {
        rc = condition.waitRelative(mutex,
                kEventTimeout);
        if (NO_ERROR != rc) {
            break;
        }
    }

    return rc;
}

TEST_F(CameraZSLTests, TestAllPictureSizes) {
    ::android::binder::Status rc;

    for (int32_t cameraId = 0; cameraId < numCameras; cameraId++) {
        sp<Surface> previewSurface;
        sp<SurfaceControl> surfaceControl;
        sp<ICamera> cameraDevice;

        std::string cameraIdStr = std::to_string(cameraId);
        bool isSupported = false;
        rc = mCameraService->supportsCameraApi(cameraIdStr,
                hardware::ICameraService::API_VERSION_1, &isSupported);
        EXPECT_TRUE(rc.isOk());

        // We only care about camera Camera1 ZSL support.
        if (!isSupported) {
            continue;
        }

        CameraMetadata metadata;
        rc = mCameraService->getCameraCharacteristics(cameraIdStr,
                /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false,
                &metadata);
        if (!rc.isOk()) {
            // The test is relevant only for cameras with Hal 3.x
            // support.
            continue;
        }
        EXPECT_FALSE(metadata.isEmpty());
        camera_metadata_entry_t availableCapabilities =
                metadata.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
        EXPECT_TRUE(0 < availableCapabilities.count);
        bool isReprocessSupported = false;
        const uint8_t *caps = availableCapabilities.data.u8;
        for (size_t i = 0; i < availableCapabilities.count; i++) {
            if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING ==
                caps[i]) {
                isReprocessSupported = true;
                break;
            }
        }
        if (!isReprocessSupported) {
            // ZSL relies on this feature
            continue;
        }

        rc = mCameraService->connect(this, cameraId,
                "ZSLTest", hardware::ICameraService::USE_CALLING_UID,
                hardware::ICameraService::USE_CALLING_PID,
                /*targetSdkVersion*/__ANDROID_API_FUTURE__,
                /*overrideToPortrait*/false, /*forceSlowJpegMode*/false, &cameraDevice);
        EXPECT_TRUE(rc.isOk());

        CameraParameters params(cameraDevice->getParameters());

        String8 focusModes(params.get(
                CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
        bool isAFSupported = false;
        const char *focusMode = nullptr;
        if (focusModes.contains(CameraParameters::FOCUS_MODE_AUTO)) {
            // If supported 'auto' should be set by default
            isAFSupported = true;
        } else if (focusModes.contains(
                CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE)) {
            isAFSupported = true;
            focusMode = CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
        } else if (focusModes.contains(
                CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO)) {
            isAFSupported = true;
            focusMode = CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
        } else if (focusModes.contains(CameraParameters::FOCUS_MODE_MACRO)) {
            isAFSupported = true;
            focusMode = CameraParameters::FOCUS_MODE_MACRO;
        }

        if (!isAFSupported) {
            // AF state is needed
            continue;
        }

        if (nullptr != focusMode) {
            params.set(CameraParameters::KEY_FOCUS_MODE, focusMode);
            ASSERT_EQ(NO_ERROR, cameraDevice->setParameters(params.flatten()));
        }

        int previewWidth, previewHeight;
        params.getPreviewSize(&previewWidth, &previewHeight);
        ASSERT_TRUE((0 < previewWidth) && (0 < previewHeight));

        surfaceControl = mComposerClient->createSurface(
                String8("Test Surface"),
                previewWidth, previewHeight,
                CameraParameters::previewFormatToEnum(
                        params.getPreviewFormat()),
                GRALLOC_USAGE_HW_RENDER);

        ASSERT_TRUE(nullptr != surfaceControl.get());
        ASSERT_TRUE(surfaceControl->isValid());

        SurfaceComposerClient::Transaction{}
                .setLayer(surfaceControl, 0x7fffffff)
                .show(surfaceControl)
                .apply();

        previewSurface = surfaceControl->getSurface();
        ASSERT_TRUE(previewSurface != NULL);
        ASSERT_EQ(NO_ERROR, cameraDevice->setPreviewTarget(
                previewSurface->getIGraphicBufferProducer()));

        cameraDevice->setPreviewCallbackFlag(
                CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER);

        Vector<Size> pictureSizes;
        params.getSupportedPictureSizes(pictureSizes);
        for (size_t i = 0; i < pictureSizes.size(); i++) {
            params.setPictureSize(pictureSizes[i].width,
                    pictureSizes[i].height);
            ASSERT_EQ(NO_ERROR, cameraDevice->setParameters(params.flatten()));
            ASSERT_EQ(NO_ERROR, cameraDevice->startPreview());
            ASSERT_EQ(NO_ERROR, waitForPreviewStart());

            ASSERT_EQ(NO_ERROR, cameraDevice->autoFocus());
            ASSERT_EQ(NO_ERROR, waitForEvent(mAutoFocusLock,
                    mAutoFocusCondition, mAutoFocusMessage));

            ASSERT_EQ(NO_ERROR,
                    cameraDevice->takePicture(CAMERA_MSG_COMPRESSED_IMAGE));
            ASSERT_EQ(NO_ERROR, waitForEvent(mSnapshotLock, mSnapshotCondition,
                    mSnapshotNotification));
        }

        cameraDevice->stopPreview();
        rc = cameraDevice->disconnect();
        EXPECT_TRUE(rc.isOk());
    }
}
