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

/*
 * Contains implementation of a class EmulatedCameraFactory that manages cameras
 * available for emulation.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "EmulatedCamera_Factory"
#include <cutils/log.h>
#include <cutils/properties.h>
#include "EmulatedQemuCamera.h"
#include "EmulatedFakeCamera.h"
#include "EmulatedFakeCamera2.h"
#include "EmulatedFakeCamera3.h"
#include "EmulatedCameraHotplugThread.h"
#include "EmulatedCameraFactory.h"

extern camera_module_t HAL_MODULE_INFO_SYM;

/* A global instance of EmulatedCameraFactory is statically instantiated and
 * initialized when camera emulation HAL is loaded.
 */
android::EmulatedCameraFactory  gEmulatedCameraFactory;

namespace android {

EmulatedCameraFactory::EmulatedCameraFactory()
        : mQemuClient(),
          mEmulatedCameras(NULL),
          mEmulatedCameraNum(0),
          mFakeCameraNum(0),
          mConstructedOK(false),
          mCallbacks(NULL)
{
    status_t res;
    /* Connect to the factory service in the emulator, and create Qemu cameras. */
    if (mQemuClient.connectClient(NULL) == NO_ERROR) {
        /* Connection has succeeded. Create emulated cameras for each camera
         * device, reported by the service. */
        createQemuCameras();
    }

    waitForQemuSfFakeCameraPropertyAvailable();

    if (isBackFakeCameraEmulationOn()) {
        /* Camera ID. */
        const int camera_id = mEmulatedCameraNum;
        /* Use fake camera to emulate back-facing camera. */
        mEmulatedCameraNum++;

        /* Make sure that array is allocated (in case there were no 'qemu'
         * cameras created. Note that we preallocate the array so it may contain
         * two fake cameras: one facing back, and another facing front. */
        if (mEmulatedCameras == NULL) {
            mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum + 1];
            if (mEmulatedCameras == NULL) {
                ALOGE("%s: Unable to allocate emulated camera array for %d entries",
                     __FUNCTION__, mEmulatedCameraNum);
                return;
            }
            memset(mEmulatedCameras, 0,
                    (mEmulatedCameraNum + 1) * sizeof(EmulatedBaseCamera*));
        }

        /* Create, and initialize the fake camera */
        switch (getBackCameraHalVersion()) {
            case 1:
                mEmulatedCameras[camera_id] =
                        new EmulatedFakeCamera(camera_id, true,
                                &HAL_MODULE_INFO_SYM.common);
                break;
            case 2:
                mEmulatedCameras[camera_id] =
                        new EmulatedFakeCamera2(camera_id, true,
                                &HAL_MODULE_INFO_SYM.common);
                break;
            case 3:
                mEmulatedCameras[camera_id] =
                        new EmulatedFakeCamera3(camera_id, true,
                                &HAL_MODULE_INFO_SYM.common);
                break;
            default:
                ALOGE("%s: Unknown back camera hal version requested: %d", __FUNCTION__,
                        getBackCameraHalVersion());
        }
        if (mEmulatedCameras[camera_id] != NULL) {
            ALOGV("%s: Back camera device version is %d", __FUNCTION__,
                    getBackCameraHalVersion());
            res = mEmulatedCameras[camera_id]->Initialize();
            if (res != NO_ERROR) {
                ALOGE("%s: Unable to intialize back camera %d: %s (%d)",
                        __FUNCTION__, camera_id, strerror(-res), res);
                delete mEmulatedCameras[camera_id];
                mEmulatedCameraNum--;
            }
        } else {
            mEmulatedCameraNum--;
            ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
        }
    }

    if (isFrontFakeCameraEmulationOn()) {
        /* Camera ID. */
        const int camera_id = mEmulatedCameraNum;
        /* Use fake camera to emulate front-facing camera. */
        mEmulatedCameraNum++;

        /* Make sure that array is allocated (in case there were no 'qemu'
         * cameras created. */
        if (mEmulatedCameras == NULL) {
            mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum];
            if (mEmulatedCameras == NULL) {
                ALOGE("%s: Unable to allocate emulated camera array for %d entries",
                     __FUNCTION__, mEmulatedCameraNum);
                return;
            }
            memset(mEmulatedCameras, 0,
                    mEmulatedCameraNum * sizeof(EmulatedBaseCamera*));
        }

        /* Create, and initialize the fake camera */
        switch (getFrontCameraHalVersion()) {
            case 1:
                mEmulatedCameras[camera_id] =
                        new EmulatedFakeCamera(camera_id, false,
                                &HAL_MODULE_INFO_SYM.common);
                break;
            case 2:
                mEmulatedCameras[camera_id] =
                        new EmulatedFakeCamera2(camera_id, false,
                                &HAL_MODULE_INFO_SYM.common);
                break;
            case 3:
                mEmulatedCameras[camera_id] =
                        new EmulatedFakeCamera3(camera_id, false,
                                &HAL_MODULE_INFO_SYM.common);
                break;
            default:
                ALOGE("%s: Unknown front camera hal version requested: %d",
                        __FUNCTION__,
                        getFrontCameraHalVersion());
        }
        if (mEmulatedCameras[camera_id] != NULL) {
            ALOGV("%s: Front camera device version is %d", __FUNCTION__,
                    getFrontCameraHalVersion());
            res = mEmulatedCameras[camera_id]->Initialize();
            if (res != NO_ERROR) {
                ALOGE("%s: Unable to intialize front camera %d: %s (%d)",
                        __FUNCTION__, camera_id, strerror(-res), res);
                delete mEmulatedCameras[camera_id];
                mEmulatedCameraNum--;
            }
        } else {
            mEmulatedCameraNum--;
            ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
        }
    }

    ALOGE("%d cameras are being emulated. %d of them are fake cameras.",
          mEmulatedCameraNum, mFakeCameraNum);

    /* Create hotplug thread */
    {
        Vector<int> cameraIdVector;
        for (int i = 0; i < mEmulatedCameraNum; ++i) {
            cameraIdVector.push_back(i);
        }
        mHotplugThread = new EmulatedCameraHotplugThread(&cameraIdVector[0],
                                                         mEmulatedCameraNum);
        mHotplugThread->run("EmulatedCameraHotplugThread");
    }

    mConstructedOK = true;
}

EmulatedCameraFactory::~EmulatedCameraFactory()
{
    if (mEmulatedCameras != NULL) {
        for (int n = 0; n < mEmulatedCameraNum; n++) {
            if (mEmulatedCameras[n] != NULL) {
                delete mEmulatedCameras[n];
            }
        }
        delete[] mEmulatedCameras;
    }

    if (mHotplugThread != NULL) {
        mHotplugThread->requestExit();
        mHotplugThread->join();
    }
}

/****************************************************************************
 * Camera HAL API handlers.
 *
 * Each handler simply verifies existence of an appropriate EmulatedBaseCamera
 * instance, and dispatches the call to that instance.
 *
 ***************************************************************************/

int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
{
    ALOGV("%s: id = %d", __FUNCTION__, camera_id);

    *device = NULL;

    if (!isConstructedOK()) {
        ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
        return -EINVAL;
    }

    if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
        ALOGE("%s: Camera id %d is out of bounds (%d)",
             __FUNCTION__, camera_id, getEmulatedCameraNum());
        return -ENODEV;
    }

    return mEmulatedCameras[camera_id]->connectCamera(device);
}

int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
{
    ALOGV("%s: id = %d", __FUNCTION__, camera_id);

    if (!isConstructedOK()) {
        ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
        return -EINVAL;
    }

    if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
        ALOGE("%s: Camera id %d is out of bounds (%d)",
             __FUNCTION__, camera_id, getEmulatedCameraNum());
        return -ENODEV;
    }

    return mEmulatedCameras[camera_id]->getCameraInfo(info);
}

int EmulatedCameraFactory::setCallbacks(
        const camera_module_callbacks_t *callbacks)
{
    ALOGV("%s: callbacks = %p", __FUNCTION__, callbacks);

    mCallbacks = callbacks;

    return OK;
}

void EmulatedCameraFactory::getVendorTagOps(vendor_tag_ops_t* ops) {
    ALOGV("%s: ops = %p", __FUNCTION__, ops);

    // No vendor tags defined for emulator yet, so not touching ops
}

/****************************************************************************
 * Camera HAL API callbacks.
 ***************************************************************************/

int EmulatedCameraFactory::device_open(const hw_module_t* module,
                                       const char* name,
                                       hw_device_t** device)
{
    /*
     * Simply verify the parameters, and dispatch the call inside the
     * EmulatedCameraFactory instance.
     */

    if (module != &HAL_MODULE_INFO_SYM.common) {
        ALOGE("%s: Invalid module %p expected %p",
             __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
        return -EINVAL;
    }
    if (name == NULL) {
        ALOGE("%s: NULL name is not expected here", __FUNCTION__);
        return -EINVAL;
    }

    return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
}

int EmulatedCameraFactory::get_number_of_cameras(void)
{
    return gEmulatedCameraFactory.getEmulatedCameraNum();
}

int EmulatedCameraFactory::get_camera_info(int camera_id,
                                           struct camera_info* info)
{
    return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
}

int EmulatedCameraFactory::set_callbacks(
        const camera_module_callbacks_t *callbacks)
{
    return gEmulatedCameraFactory.setCallbacks(callbacks);
}

void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t* ops)
{
    gEmulatedCameraFactory.getVendorTagOps(ops);
}

int EmulatedCameraFactory::open_legacy(const struct hw_module_t* module,
        const char* id, uint32_t halVersion, struct hw_device_t** device) {
    // Not supporting legacy open
    return -ENOSYS;
}

/********************************************************************************
 * Internal API
 *******************************************************************************/

/*
 * Camera information tokens passed in response to the "list" factory query.
 */

/* Device name token. */
static const char lListNameToken[]    = "name=";
/* Frame dimensions token. */
static const char lListDimsToken[]    = "framedims=";
/* Facing direction token. */
static const char lListDirToken[]     = "dir=";

void EmulatedCameraFactory::createQemuCameras()
{
    /* Obtain camera list. */
    char* camera_list = NULL;
    status_t res = mQemuClient.listCameras(&camera_list);
    /* Empty list, or list containing just an EOL means that there were no
     * connected cameras found. */
    if (res != NO_ERROR || camera_list == NULL || *camera_list == '\0' ||
        *camera_list == '\n') {
        if (camera_list != NULL) {
            free(camera_list);
        }
        return;
    }

    /*
     * Calculate number of connected cameras. Number of EOLs in the camera list
     * is the number of the connected cameras.
     */

    int num = 0;
    const char* eol = strchr(camera_list, '\n');
    while (eol != NULL) {
        num++;
        eol = strchr(eol + 1, '\n');
    }

    /* Allocate the array for emulated camera instances. Note that we allocate
     * two more entries for back and front fake camera emulation. */
    mEmulatedCameras = new EmulatedBaseCamera*[num + 2];
    if (mEmulatedCameras == NULL) {
        ALOGE("%s: Unable to allocate emulated camera array for %d entries",
             __FUNCTION__, num + 1);
        free(camera_list);
        return;
    }
    memset(mEmulatedCameras, 0, sizeof(EmulatedBaseCamera*) * (num + 1));

    /*
     * Iterate the list, creating, and initializin emulated qemu cameras for each
     * entry (line) in the list.
     */

    int index = 0;
    char* cur_entry = camera_list;
    while (cur_entry != NULL && *cur_entry != '\0' && index < num) {
        /* Find the end of the current camera entry, and terminate it with zero
         * for simpler string manipulation. */
        char* next_entry = strchr(cur_entry, '\n');
        if (next_entry != NULL) {
            *next_entry = '\0';
            next_entry++;   // Start of the next entry.
        }

        /* Find 'name', 'framedims', and 'dir' tokens that are required here. */
        char* name_start = strstr(cur_entry, lListNameToken);
        char* dim_start = strstr(cur_entry, lListDimsToken);
        char* dir_start = strstr(cur_entry, lListDirToken);
        if (name_start != NULL && dim_start != NULL && dir_start != NULL) {
            /* Advance to the token values. */
            name_start += strlen(lListNameToken);
            dim_start += strlen(lListDimsToken);
            dir_start += strlen(lListDirToken);

            /* Terminate token values with zero. */
            char* s = strchr(name_start, ' ');
            if (s != NULL) {
                *s = '\0';
            }
            s = strchr(dim_start, ' ');
            if (s != NULL) {
                *s = '\0';
            }
            s = strchr(dir_start, ' ');
            if (s != NULL) {
                *s = '\0';
            }

            /* Create and initialize qemu camera. */
            EmulatedQemuCamera* qemu_cam =
                new EmulatedQemuCamera(index, &HAL_MODULE_INFO_SYM.common);
            if (NULL != qemu_cam) {
                res = qemu_cam->Initialize(name_start, dim_start, dir_start);
                if (res == NO_ERROR) {
                    mEmulatedCameras[index] = qemu_cam;
                    index++;
                } else {
                    delete qemu_cam;
                }
            } else {
                ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
                     __FUNCTION__);
            }
        } else {
            ALOGW("%s: Bad camera information: %s", __FUNCTION__, cur_entry);
        }

        cur_entry = next_entry;
    }

    mEmulatedCameraNum = index;
}

void EmulatedCameraFactory::waitForQemuSfFakeCameraPropertyAvailable() {
    // Camera service may start running before qemu-props sets qemu.sf.fake_camera to
    // any of the follwing four values: "none,front,back,both"; so we need to wait.
    // android/camera/camera-service.c
    // bug: 30768229
    int numAttempts = 100;
    char prop[PROPERTY_VALUE_MAX];
    bool timeout = true;
    for (int i = 0; i < numAttempts; ++i) {
        if (property_get("qemu.sf.fake_camera", prop, NULL) != 0 ) {
            timeout = false;
            break;
        }
        usleep(5000);
    }
    if (timeout) {
        ALOGE("timeout (%dms) waiting for property qemu.sf.fake_camera to be set\n", 5 * numAttempts);
    }
}

bool EmulatedCameraFactory::isBackFakeCameraEmulationOn()
{
    /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
     * is set to 'both', or 'back', then fake camera is used to emulate back
     * camera. */
    char prop[PROPERTY_VALUE_MAX];
    if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
        (!strcmp(prop, "both") || !strcmp(prop, "back"))) {
        return true;
    } else {
        return false;
    }
}

int EmulatedCameraFactory::getBackCameraHalVersion()
{
    /* Defined by 'qemu.sf.back_camera_hal_version' boot property: if the
     * property doesn't exist, it is assumed to be 1. */
    char prop[PROPERTY_VALUE_MAX];
    if (property_get("qemu.sf.back_camera_hal", prop, NULL) > 0) {
        char *prop_end = prop;
        int val = strtol(prop, &prop_end, 10);
        if (*prop_end == '\0') {
            return val;
        }
        // Badly formatted property, should just be a number
        ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop);
    }
    return 1;
}

bool EmulatedCameraFactory::isFrontFakeCameraEmulationOn()
{
    /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
     * is set to 'both', or 'front', then fake camera is used to emulate front
     * camera. */
    char prop[PROPERTY_VALUE_MAX];
    if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
        (!strcmp(prop, "both") || !strcmp(prop, "front"))) {
        return true;
    } else {
        return false;
    }
}

int EmulatedCameraFactory::getFrontCameraHalVersion()
{
    /* Defined by 'qemu.sf.front_camera_hal_version' boot property: if the
     * property doesn't exist, it is assumed to be 1. */
    char prop[PROPERTY_VALUE_MAX];
    if (property_get("qemu.sf.front_camera_hal", prop, NULL) > 0) {
        char *prop_end = prop;
        int val = strtol(prop, &prop_end, 10);
        if (*prop_end == '\0') {
            return val;
        }
        // Badly formatted property, should just be a number
        ALOGE("qemu.sf.front_camera_hal is not a number: %s", prop);
    }
    return 1;
}

void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) {

    EmulatedBaseCamera *cam = mEmulatedCameras[cameraId];
    if (!cam) {
        ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
        return;
    }

    /**
     * (Order is important)
     * Send the callback first to framework, THEN close the camera.
     */

    if (newStatus == cam->getHotplugStatus()) {
        ALOGW("%s: Ignoring transition to the same status", __FUNCTION__);
        return;
    }

    const camera_module_callbacks_t* cb = mCallbacks;
    if (cb != NULL && cb->camera_device_status_change != NULL) {
        cb->camera_device_status_change(cb, cameraId, newStatus);
    }

    if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
        cam->unplugCamera();
    } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) {
        cam->plugCamera();
    }

}

/********************************************************************************
 * Initializer for the static member structure.
 *******************************************************************************/

/* Entry point for camera HAL API. */
struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
    open: EmulatedCameraFactory::device_open
};

}; /* namespace android */
