/*
 * Copyright (C) 2013 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 "EmulatedCamera_HotplugThread"
#include <cutils/log.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/inotify.h>

#include "EmulatedCameraHotplugThread.h"
#include "EmulatedCameraFactory.h"

#define FAKE_HOTPLUG_FILE "/data/misc/media/emulator.camera.hotplug"

#define EVENT_SIZE (sizeof(struct inotify_event))
#define EVENT_BUF_LEN (1024*(EVENT_SIZE+16))

#define SubscriberInfo EmulatedCameraHotplugThread::SubscriberInfo

namespace android {

EmulatedCameraHotplugThread::EmulatedCameraHotplugThread(
    const int* cameraIdArray,
    size_t size) :
        Thread(/*canCallJava*/false) {

    mRunning = true;
    mInotifyFd = 0;

    for (size_t i = 0; i < size; ++i) {
        int id = cameraIdArray[i];

        if (createFileIfNotExists(id)) {
            mSubscribedCameraIds.push_back(id);
        }
    }
}

EmulatedCameraHotplugThread::~EmulatedCameraHotplugThread() {
}

status_t EmulatedCameraHotplugThread::requestExitAndWait() {
    ALOGE("%s: Not implemented. Use requestExit + join instead",
          __FUNCTION__);
    return INVALID_OPERATION;
}

void EmulatedCameraHotplugThread::requestExit() {
    Mutex::Autolock al(mMutex);

    ALOGV("%s: Requesting thread exit", __FUNCTION__);
    mRunning = false;

    bool rmWatchFailed = false;
    Vector<SubscriberInfo>::iterator it;
    for (it = mSubscribers.begin(); it != mSubscribers.end(); ++it) {

        if (inotify_rm_watch(mInotifyFd, it->WatchID) == -1) {

            ALOGE("%s: Could not remove watch for camID '%d',"
                  " error: '%s' (%d)",
                 __FUNCTION__, it->CameraID, strerror(errno),
                 errno);

            rmWatchFailed = true ;
        } else {
            ALOGV("%s: Removed watch for camID '%d'",
                __FUNCTION__, it->CameraID);
        }
    }

    if (rmWatchFailed) { // unlikely
        // Give the thread a fighting chance to error out on the next
        // read
        if (TEMP_FAILURE_RETRY(close(mInotifyFd)) == -1) {
            ALOGE("%s: close failure error: '%s' (%d)",
                 __FUNCTION__, strerror(errno), errno);
        }
    }

    ALOGV("%s: Request exit complete.", __FUNCTION__);
}

status_t EmulatedCameraHotplugThread::readyToRun() {
    Mutex::Autolock al(mMutex);

    mInotifyFd = -1;

    do {
        ALOGV("%s: Initializing inotify", __FUNCTION__);

        mInotifyFd = inotify_init();
        if (mInotifyFd == -1) {
            ALOGE("%s: inotify_init failure error: '%s' (%d)",
                 __FUNCTION__, strerror(errno), errno);
            mRunning = false;
            break;
        }

        /**
         * For each fake camera file, add a watch for when
         * the file is closed (if it was written to)
         */
        Vector<int>::const_iterator it, end;
        it = mSubscribedCameraIds.begin();
        end = mSubscribedCameraIds.end();
        for (; it != end; ++it) {
            int cameraId = *it;
            if (!addWatch(cameraId)) {
                mRunning = false;
                break;
            }
        }
    } while(false);

    if (!mRunning) {
        status_t err = -errno;

        if (mInotifyFd != -1) {
            TEMP_FAILURE_RETRY(close(mInotifyFd));
        }

        return err;
    }

    return OK;
}

bool EmulatedCameraHotplugThread::threadLoop() {

    // If requestExit was already called, mRunning will be false
    while (mRunning) {
        char buffer[EVENT_BUF_LEN];
        int length = TEMP_FAILURE_RETRY(
                        read(mInotifyFd, buffer, EVENT_BUF_LEN));

        if (length < 0) {
            ALOGE("%s: Error reading from inotify FD, error: '%s' (%d)",
                 __FUNCTION__, strerror(errno),
                 errno);
            mRunning = false;
            break;
        }

        ALOGV("%s: Read %d bytes from inotify FD", __FUNCTION__, length);

        int i = 0;
        while (i < length) {
            inotify_event* event = (inotify_event*) &buffer[i];

            if (event->mask & IN_IGNORED) {
                Mutex::Autolock al(mMutex);
                if (!mRunning) {
                    ALOGV("%s: Shutting down thread", __FUNCTION__);
                    break;
                } else {
                    ALOGE("%s: File was deleted, aborting",
                          __FUNCTION__);
                    mRunning = false;
                    break;
                }
            } else if (event->mask & IN_CLOSE_WRITE) {
                int cameraId = getCameraId(event->wd);

                if (cameraId < 0) {
                    ALOGE("%s: Got bad camera ID from WD '%d",
                          __FUNCTION__, event->wd);
                } else {
                    // Check the file for the new hotplug event
                    String8 filePath = getFilePath(cameraId);
                    /**
                     * NOTE: we carefully avoid getting an inotify
                     * for the same exact file because it's opened for
                     * read-only, but our inotify is for write-only
                     */
                    int newStatus = readFile(filePath);

                    if (newStatus < 0) {
                        mRunning = false;
                        break;
                    }

                    int halStatus = newStatus ?
                        CAMERA_DEVICE_STATUS_PRESENT :
                        CAMERA_DEVICE_STATUS_NOT_PRESENT;
                    gEmulatedCameraFactory.onStatusChanged(cameraId,
                                                           halStatus);
                }

            } else {
                ALOGW("%s: Unknown mask 0x%x",
                      __FUNCTION__, event->mask);
            }

            i += EVENT_SIZE + event->len;
        }
    }

    if (!mRunning) {
        TEMP_FAILURE_RETRY(close(mInotifyFd));
        return false;
    }

    return true;
}

String8 EmulatedCameraHotplugThread::getFilePath(int cameraId) const {
    return String8::format(FAKE_HOTPLUG_FILE ".%d", cameraId);
}

bool EmulatedCameraHotplugThread::createFileIfNotExists(int cameraId) const
{
    String8 filePath = getFilePath(cameraId);
    // make sure this file exists and we have access to it
    int fd = TEMP_FAILURE_RETRY(
                open(filePath.string(), O_WRONLY | O_CREAT | O_TRUNC,
                     /* mode = ug+rwx */ S_IRWXU | S_IRWXG ));
    if (fd == -1) {
        ALOGE("%s: Could not create file '%s', error: '%s' (%d)",
             __FUNCTION__, filePath.string(), strerror(errno), errno);
        return false;
    }

    // File has '1' by default since we are plugged in by default
    if (TEMP_FAILURE_RETRY(write(fd, "1\n", /*count*/2)) == -1) {
        ALOGE("%s: Could not write '1' to file '%s', error: '%s' (%d)",
             __FUNCTION__, filePath.string(), strerror(errno), errno);
        return false;
    }

    TEMP_FAILURE_RETRY(close(fd));
    return true;
}

int EmulatedCameraHotplugThread::getCameraId(String8 filePath) const {
    Vector<int>::const_iterator it, end;
    it = mSubscribedCameraIds.begin();
    end = mSubscribedCameraIds.end();
    for (; it != end; ++it) {
        String8 camPath = getFilePath(*it);

        if (camPath == filePath) {
            return *it;
        }
    }

    return NAME_NOT_FOUND;
}

int EmulatedCameraHotplugThread::getCameraId(int wd) const {
    for (size_t i = 0; i < mSubscribers.size(); ++i) {
        if (mSubscribers[i].WatchID == wd) {
            return mSubscribers[i].CameraID;
        }
    }

    return NAME_NOT_FOUND;
}

SubscriberInfo* EmulatedCameraHotplugThread::getSubscriberInfo(int cameraId)
{
    for (size_t i = 0; i < mSubscribers.size(); ++i) {
        if (mSubscribers[i].CameraID == cameraId) {
            return (SubscriberInfo*)&mSubscribers[i];
        }
    }

    return NULL;
}

bool EmulatedCameraHotplugThread::addWatch(int cameraId) {
    String8 camPath = getFilePath(cameraId);
    int wd = inotify_add_watch(mInotifyFd,
                               camPath.string(),
                               IN_CLOSE_WRITE);

    if (wd == -1) {
        ALOGE("%s: Could not add watch for '%s', error: '%s' (%d)",
             __FUNCTION__, camPath.string(), strerror(errno),
             errno);

        mRunning = false;
        return false;
    }

    ALOGV("%s: Watch added for camID='%d', wd='%d'",
          __FUNCTION__, cameraId, wd);

    SubscriberInfo si = { cameraId, wd };
    mSubscribers.push_back(si);

    return true;
}

bool EmulatedCameraHotplugThread::removeWatch(int cameraId) {
    SubscriberInfo* si = getSubscriberInfo(cameraId);

    if (!si) return false;

    if (inotify_rm_watch(mInotifyFd, si->WatchID) == -1) {

        ALOGE("%s: Could not remove watch for camID '%d', error: '%s' (%d)",
             __FUNCTION__, cameraId, strerror(errno),
             errno);

        return false;
    }

    Vector<SubscriberInfo>::iterator it;
    for (it = mSubscribers.begin(); it != mSubscribers.end(); ++it) {
        if (it->CameraID == cameraId) {
            break;
        }
    }

    if (it != mSubscribers.end()) {
        mSubscribers.erase(it);
    }

    return true;
}

int EmulatedCameraHotplugThread::readFile(String8 filePath) const {

    int fd = TEMP_FAILURE_RETRY(
                open(filePath.string(), O_RDONLY, /*mode*/0));
    if (fd == -1) {
        ALOGE("%s: Could not open file '%s', error: '%s' (%d)",
             __FUNCTION__, filePath.string(), strerror(errno), errno);
        return -1;
    }

    char buffer[1];
    int length;

    length = TEMP_FAILURE_RETRY(
                    read(fd, buffer, sizeof(buffer)));

    int retval;

    ALOGV("%s: Read file '%s', length='%d', buffer='%c'",
         __FUNCTION__, filePath.string(), length, buffer[0]);

    if (length == 0) { // EOF
        retval = 0; // empty file is the same thing as 0
    } else if (buffer[0] == '0') {
        retval = 0;
    } else { // anything non-empty that's not beginning with '0'
        retval = 1;
    }

    TEMP_FAILURE_RETRY(close(fd));

    return retval;
}

} //namespace android
