/*
 * 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 "EmulatedCameraFactory.h"
#include "EmulatedCameraHotplugThread.h"
#include "EmulatedFakeCamera.h"
#include "EmulatedFakeCamera2.h"
#include "EmulatedFakeCamera3.h"
#include "EmulatedQemuCamera.h"
#include "EmulatedQemuCamera3.h"

#include <log/log.h>
#include <cutils/properties.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(nullptr),
        mEmulatedCameraNum(0),
        mFakeCameraNum(0),
        mConstructedOK(false),
        mCallbacks(nullptr) {

    /*
     * Figure out how many cameras need to be created, so we can allocate the
     * array of emulated cameras before populating it.
     */
    int emulatedCamerasSize = 0;

    // QEMU Cameras
    std::vector<QemuCameraInfo> qemuCameras;
    if (mQemuClient.connectClient(nullptr) == NO_ERROR) {
        findQemuCameras(&qemuCameras);
        emulatedCamerasSize += qemuCameras.size();
    }

    waitForQemuSfFakeCameraPropertyAvailable();
    // Fake Cameras
    if (isFakeCameraEmulationOn(/* backCamera */ true)) {
        mFakeCameraNum++;
    }
    if (isFakeCameraEmulationOn(/* backCamera */ false)) {
        mFakeCameraNum++;
    }
    emulatedCamerasSize += mFakeCameraNum;

    /*
     * We have the number of cameras we need to create, now allocate space for
     * them.
     */
    mEmulatedCameras = new EmulatedBaseCamera*[emulatedCamerasSize];
    if (mEmulatedCameras == nullptr) {
        ALOGE("%s: Unable to allocate emulated camera array for %d entries",
                __FUNCTION__, mEmulatedCameraNum);
        return;
    }

    createQemuCameras(qemuCameras);

    // Create fake cameras, if enabled.
    if (isFakeCameraEmulationOn(/* backCamera */ true)) {
        createFakeCamera(/* backCamera */ true);
    }
    if (isFakeCameraEmulationOn(/* backCamera */ false)) {
        createFakeCamera(/* backCamera */ false);
    }

    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 != nullptr) {
        for (int n = 0; n < mEmulatedCameraNum; n++) {
            if (mEmulatedCameras[n] != nullptr) {
                delete mEmulatedCameras[n];
            }
        }
        delete[] mEmulatedCameras;
    }

    if (mHotplugThread != nullptr) {
        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 cameraId,
                                            hw_device_t **device) {
    ALOGV("%s: id = %d", __FUNCTION__, cameraId);

    *device = nullptr;

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

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

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

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

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

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

    return mEmulatedCameras[cameraId]->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 == nullptr) {
        ALOGE("%s: NULL name is not expected here", __FUNCTION__);
        return -EINVAL;
    }

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

int EmulatedCameraFactory::get_number_of_cameras() {
    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 *kListNameToken = "name=";
// Frame dimensions token.
static const char *kListDimsToken = "framedims=";
// Facing direction token.
static const char *kListDirToken = "dir=";


bool EmulatedCameraFactory::getTokenValue(const char *token,
        const std::string &s, char **value) {
    // Find the start of the token.
    size_t tokenStart = s.find(token);
    if (tokenStart == std::string::npos) {
        return false;
    }

    // Advance to the beginning of the token value.
    size_t valueStart = tokenStart + strlen(token);

    // Find the length of the token value.
    size_t valueLength = s.find(' ', valueStart) - valueStart;

    // Extract the value substring.
    std::string valueStr = s.substr(valueStart, valueLength);

    // Convert to char*.
    *value = new char[valueStr.length() + 1];
    if (*value == nullptr) {
        return false;
    }
    strcpy(*value, valueStr.c_str());

    ALOGV("%s: Parsed value is \"%s\"", __FUNCTION__, *value);

    return true;
}

void EmulatedCameraFactory::findQemuCameras(
        std::vector<QemuCameraInfo> *qemuCameras) {
    // Obtain camera list.
    char *cameraList = nullptr;
    status_t res = mQemuClient.listCameras(&cameraList);

    /*
     * Empty list, or list containing just an EOL means that there were no
     * connected cameras found.
     */
    if (res != NO_ERROR || cameraList == nullptr || *cameraList == '\0' ||
        *cameraList == '\n') {
        if (cameraList != nullptr) {
            free(cameraList);
        }
        return;
    }

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

    std::string cameraListStr(cameraList);
    free(cameraList);

    size_t lineBegin = 0;
    size_t lineEnd = cameraListStr.find('\n');
    while (lineEnd != std::string::npos) {
        std::string cameraStr = cameraListStr.substr(lineBegin, lineEnd - lineBegin);
        // Parse the 'name', 'framedims', and 'dir' tokens.
        char *name, *frameDims, *dir;
        if (getTokenValue(kListNameToken, cameraStr, &name) &&
                getTokenValue(kListDimsToken, cameraStr, &frameDims) &&
                getTokenValue(kListDirToken, cameraStr, &dir)) {
            // Push the camera info if it was all successfully parsed.
            qemuCameras->push_back(QemuCameraInfo{
                .name = name,
                .frameDims = frameDims,
                .dir = dir,
            });
        } else {
            ALOGW("%s: Bad camera information: %s", __FUNCTION__,
                    cameraStr.c_str());
        }
        // Skip over the newline for the beginning of the next line.
        lineBegin = lineEnd + 1;
        lineEnd = cameraListStr.find('\n', lineBegin);
    }
}

void EmulatedCameraFactory::createQemuCameras(
        const std::vector<QemuCameraInfo> &qemuCameras) {
    /*
     * Iterate the list, creating, and initializing emulated QEMU cameras for each
     * entry in the list.
     */

    /*
     * We use this index only for determining which direction the webcam should
     * face. Otherwise, mEmulatedCameraNum represents the camera ID and the
     * index into mEmulatedCameras.
     */
    int qemuIndex = 0;
    for (const auto &cameraInfo : qemuCameras) {
        /*
         * Here, we're assuming the first webcam is intended to be the back
         * camera and any other webcams are front cameras.
         */
        int halVersion = 0;
        if (qemuIndex == 0) {
            halVersion = getCameraHalVersion(/* backCamera */ true);
        } else {
            halVersion = getCameraHalVersion(/* backCamera */ false);
        }

        // Create and initialize QEMU camera.
        EmulatedBaseCamera *qemuCam = nullptr;
        status_t res;
        switch (halVersion) {
            case 1:
                EmulatedQemuCamera *qemuCamOne;
                qemuCamOne = new EmulatedQemuCamera(
                        mEmulatedCameraNum, &HAL_MODULE_INFO_SYM.common);
                if (qemuCamOne == nullptr) {
                    ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
                            __FUNCTION__);
                } else {
                    /*
                     * We have to initialize in each switch case, because
                     * EmulatedBaseCamera::Initialize has a different method
                     * signature.
                     *
                     * TODO: Having an EmulatedBaseQemuCamera class
                     * could fix this issue.
                     */
                    res = qemuCamOne->Initialize(
                            cameraInfo.name,
                            cameraInfo.frameDims,
                            cameraInfo.dir);
                }
                qemuCam = qemuCamOne;
                break;
            case 2:
                ALOGE("%s: QEMU support for camera hal version %d is not "
                        "implemented", __FUNCTION__, halVersion);
                break;
            case 3:
                EmulatedQemuCamera3 *qemuCamThree;
                qemuCamThree = new EmulatedQemuCamera3(
                        mEmulatedCameraNum, &HAL_MODULE_INFO_SYM.common);
                if (qemuCamThree == nullptr) {
                    ALOGE("%s: Unable to instantiate EmulatedQemuCamera3",
                            __FUNCTION__);
                } else {
                    res = qemuCamThree->Initialize(
                            cameraInfo.name,
                            cameraInfo.frameDims,
                            cameraInfo.dir);
                }
                qemuCam = qemuCamThree;
                break;
            default:
                ALOGE("%s: Unknown camera hal version requested: %d",
                        __FUNCTION__, halVersion);
        }

        if (qemuCam == nullptr) {
            ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
                    __FUNCTION__);
        } else {
            if (res == NO_ERROR) {
                mEmulatedCameras[mEmulatedCameraNum] = qemuCam;
                qemuIndex++;
                mEmulatedCameraNum++;
            } else {
                delete qemuCam;
            }
        }
    }
}

void EmulatedCameraFactory::createFakeCamera(bool backCamera) {
    int halVersion = getCameraHalVersion(backCamera);

    /*
     * Create and initialize the fake camera, using the index into
     * mEmulatedCameras as the camera ID.
     */
    switch (halVersion) {
        case 1:
            mEmulatedCameras[mEmulatedCameraNum] =
                    new EmulatedFakeCamera(mEmulatedCameraNum, backCamera,
                            &HAL_MODULE_INFO_SYM.common);
            break;
        case 2:
            mEmulatedCameras[mEmulatedCameraNum] =
                    new EmulatedFakeCamera2(mEmulatedCameraNum, backCamera,
                            &HAL_MODULE_INFO_SYM.common);
            break;
        case 3:
            {
                const char *key = "ro.kernel.qemu.camera.fake.rotating";
                char prop[PROPERTY_VALUE_MAX];
                if (property_get(key, prop, nullptr) > 0) {
                    mEmulatedCameras[mEmulatedCameraNum] =
                        new EmulatedFakeCamera(mEmulatedCameraNum, backCamera,
                                &HAL_MODULE_INFO_SYM.common);
                } else {
                    mEmulatedCameras[mEmulatedCameraNum] =
                        new EmulatedFakeCamera3(mEmulatedCameraNum, backCamera,
                                &HAL_MODULE_INFO_SYM.common);
                }
            }
            break;
        default:
            ALOGE("%s: Unknown %s camera hal version requested: %d",
                    __FUNCTION__, backCamera ? "back" : "front", halVersion);
    }

    if (mEmulatedCameras[mEmulatedCameraNum] == nullptr) {
        ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
    } else {
        ALOGV("%s: %s camera device version is %d", __FUNCTION__,
                backCamera ? "Back" : "Front", halVersion);
        status_t res = mEmulatedCameras[mEmulatedCameraNum]->Initialize();
        if (res == NO_ERROR) {
            // Camera creation and initialization was successful.
            mEmulatedCameraNum++;
        } else {
            ALOGE("%s: Unable to initialize %s camera %d: %s (%d)",
                    __FUNCTION__, backCamera ? "back" : "front",
                    mEmulatedCameraNum, strerror(-res), res);
            delete mEmulatedCameras[mEmulatedCameraNum];
        }
    }
}

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, nullptr) != 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::isFakeCameraEmulationOn(bool backCamera) {
    /*
     * Defined by 'qemu.sf.fake_camera' boot property. If the property exists,
     * and if it's set to 'both', then fake cameras are used to emulate both
     * sides. If it's set to 'back' or 'front', then a fake camera is used only
     * to emulate the back or front camera, respectively.
     */
    char prop[PROPERTY_VALUE_MAX];
    if ((property_get("qemu.sf.fake_camera", prop, nullptr) > 0) &&
        (!strcmp(prop, "both") ||
         !strcmp(prop, backCamera ? "back" : "front"))) {
        return true;
    } else {
        return false;
    }
}

int EmulatedCameraFactory::getCameraHalVersion(bool backCamera) {
    /*
     * Defined by 'qemu.sf.front_camera_hal_version' and
     * 'qemu.sf.back_camera_hal_version' boot properties. If the property
     * doesn't exist, it is assumed we are working with HAL v1.
     */
    char prop[PROPERTY_VALUE_MAX];
    const char *propQuery = backCamera ?
            "qemu.sf.back_camera_hal" :
            "qemu.sf.front_camera_hal";
    if (property_get(propQuery, prop, nullptr) > 0) {
        char *propEnd = prop;
        int val = strtol(prop, &propEnd, 10);
        if (*propEnd == '\0') {
            return val;
        }
        // Badly formatted property. It should just be a number.
        ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop);
    }
    return 3;
}

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 != nullptr && cb->camera_device_status_change != nullptr) {
        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
};

}; // end of namespace android
