/*
 * 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/CameraUtils.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, kDefaultDeviceId, /*devicePolicy*/0,
            &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,
                kDefaultDeviceId, /*devicePolicy*/0, &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, kDefaultDeviceId,
                /*devicePolicy*/0, &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());
    }
}
