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

#ifndef __ANDROID_HAL_CAMERA2_TESTS_MODULE_FIXTURE__
#define __ANDROID_HAL_CAMERA2_TESTS_MODULE_FIXTURE__

#include <gtest/gtest.h>

#include "hardware/hardware.h"
#include "hardware/camera2.h"

#include <common/CameraModule.h>
#include <device3/Camera3Device.h>

#include "camera2_utils.h"
#include "TestExtensions.h"

namespace android {
namespace camera2 {
namespace tests {

template <bool InfoQuirk = false>
struct CameraModuleFixture {

    explicit CameraModuleFixture(int CameraID = -1) {
        TEST_EXTENSION_FORKING_CONSTRUCTOR;

        mCameraID = CameraID;
    }

    ~CameraModuleFixture() {
        TEST_EXTENSION_FORKING_DESTRUCTOR;
    }

    camera_metadata_ro_entry GetStaticEntry(uint32_t tag) const {
        const CameraMetadata& staticInfo = mDevice->info();
        camera_metadata_ro_entry entry = staticInfo.find(tag);
        return entry;
    }

    void SetUp() {
        TEST_EXTENSION_FORKING_SET_UP;

        camera_module_t *rawModule;
        ASSERT_LE(0, hw_get_module(CAMERA_HARDWARE_MODULE_ID,
            (const hw_module_t **)&rawModule)) << "Could not load camera module";
        ASSERT_NE((void*)0, rawModule);
        mModule = new CameraModule(rawModule);

        mNumberOfCameras = mModule->getNumberOfCameras();
        ASSERT_LE(0, mNumberOfCameras);

        ASSERT_LE(
            CAMERA_MODULE_API_VERSION_2_0, mModule->getModuleApiVersion())
            << "Wrong module API version";

        /* For using this fixture in other tests only */
        SetUpMixin();
    }

    void TearDown() {
        TEST_EXTENSION_FORKING_TEAR_DOWN;

        TearDownMixin();

        /* important: device must be destructed before closing module,
           since it calls back into HAL */
        mDevice.clear();

        if (!TEST_EXTENSION_FORKING_ENABLED) {
            ASSERT_EQ(0, HWModuleHelpers::closeModule(mModule->getDso()))
                << "Failed to close camera HAL module";
        }
        delete mModule;
    }

    void CreateCamera(int cameraID, /*out*/ sp<CameraDeviceBase> *device) {
        struct camera_info info;
        ASSERT_EQ(OK, mModule->getCameraInfo(cameraID, &info));

        ASSERT_GE((int)info.device_version, CAMERA_DEVICE_API_VERSION_3_0) <<
                "Device version too old for camera " << cameraID << ". Version: " <<
                info.device_version;
        switch(info.device_version) {
            case CAMERA_DEVICE_API_VERSION_3_0:
            case CAMERA_DEVICE_API_VERSION_3_1:
            case CAMERA_DEVICE_API_VERSION_3_2:
                *device = new Camera3Device(String8::format("%d", cameraID));
                break;
            default:
                device->clear();
                FAIL() << "Device version unknown for camera " << cameraID << ". Version: " <<
                       info.device_version;
        }

    }

    int getDeviceVersion() {
        return getDeviceVersion(mCameraID);
    }

    int getDeviceVersion(int cameraId, status_t* status = NULL) {
        camera_info info;
        status_t res;
        res = mModule->getCameraInfo(cameraId, &info);
        if (status != NULL) *status = res;

        return info.device_version;
    }

private:

    void SetUpMixin() {
        /* For using this fixture in other tests only */
        if (mCameraID != -1) {
            EXPECT_LE(0, mCameraID);
            EXPECT_LT(mCameraID, mNumberOfCameras);

            /* HALBUG (Exynos5); crashes if we skip calling get_camera_info
               before initializing. Need info anyway now. */

            CreateCamera(mCameraID, &mDevice);

            ASSERT_TRUE(mDevice != NULL) << "Failed to open device " << mCameraID;
            ASSERT_EQ(OK, mDevice->initialize(mModule))
                << "Failed to initialize device " << mCameraID;
        }
    }

    void TearDownMixin() {

    }

protected:
    int mNumberOfCameras;
    CameraModule *mModule;
    sp<CameraDeviceBase> mDevice;

private:
    int mCameraID;
};


}
}
}

#endif
