/*
 * 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 "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)
{
    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();
    }

    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;
            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;
            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__);
        }
    }

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

    mConstructedOK = true;
}

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

/****************************************************************************
 * 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);
}

/****************************************************************************
 * 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);
}

/********************************************************************************
 * 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;
}

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;
}

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