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

#include <hardware/sensors.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <math.h>
#include <poll.h>
#include <pthread.h>
#include <cutils/atomic.h>

#define LOG_NDEBUG 1
#include <cutils/log.h>

#include <vector>
#include <map>

#include <stdio.h>
#include <dlfcn.h>
#include <SensorEventQueue.h>


static const char* CONFIG_FILENAME = "/system/etc/sensors/hals.conf";
static const char* LEGAL_SUBHAL_PATH_PREFIX = "/system/lib/hw/";
static const int MAX_CONF_LINE_LENGTH = 1024;

static pthread_mutex_t init_modules_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t init_sensors_mutex = PTHREAD_MUTEX_INITIALIZER;

// This mutex is shared by all queues
static pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;

// Used to pause the multihal poll(). Broadcasted by sub-polling tasks if waiting_for_data.
static pthread_cond_t data_available_cond = PTHREAD_COND_INITIALIZER;
bool waiting_for_data = false;

/*
 * Vector of sub modules, whose indexes are referred to ni this file as module_index.
 */
static std::vector<hw_module_t *> *sub_hw_modules = NULL;

/*
 * Comparable class that globally identifies a sensor, by module index and local handle.
 * A module index is the module's index in sub_hw_modules.
 * A local handle is the handle the sub-module assigns to a sensor.
 */
struct FullHandle {
    int moduleIndex;
    int localHandle;

    bool operator<(const FullHandle &that) const {
        if (moduleIndex < that.moduleIndex) {
            return true;
        }
        if (moduleIndex > that.moduleIndex) {
            return false;
        }
        return localHandle < that.localHandle;
    }

    bool operator==(const FullHandle &that) const {
        return moduleIndex == that.moduleIndex && localHandle == that.localHandle;
    }
};

std::map<int, FullHandle> global_to_full;
std::map<FullHandle, int> full_to_global;
int next_global_handle = 1;

static int assign_global_handle(int module_index, int local_handle) {
    int global_handle = next_global_handle++;
    FullHandle full_handle;
    full_handle.moduleIndex = module_index;
    full_handle.localHandle = local_handle;
    full_to_global[full_handle] = global_handle;
    global_to_full[global_handle] = full_handle;
    return global_handle;
}

static int get_local_handle(int global_handle) {
    return global_to_full[global_handle].localHandle;
}

static int get_module_index(int global_handle) {
    FullHandle f = global_to_full[global_handle];
    ALOGV("FullHandle for global_handle %d: moduleIndex %d, localHandle %d",
            global_handle, f.moduleIndex, f.localHandle);
    return f.moduleIndex;
}

static const int SENSOR_EVENT_QUEUE_CAPACITY = 20;

struct TaskContext {
  sensors_poll_device_t* device;
  SensorEventQueue* queue;
};

void *writerTask(void* ptr) {
    ALOGV("writerTask STARTS");
    TaskContext* ctx = (TaskContext*)ptr;
    sensors_poll_device_t* device = ctx->device;
    SensorEventQueue* queue = ctx->queue;
    sensors_event_t* buffer;
    int eventsPolled;
    while (1) {
        pthread_mutex_lock(&queue_mutex);
        if (queue->waitForSpace(&queue_mutex)) {
            ALOGV("writerTask waited for space");
        }
        int bufferSize = queue->getWritableRegion(SENSOR_EVENT_QUEUE_CAPACITY, &buffer);
        // Do blocking poll outside of lock
        pthread_mutex_unlock(&queue_mutex);

        ALOGV("writerTask before poll() - bufferSize = %d", bufferSize);
        eventsPolled = device->poll(device, buffer, bufferSize);
        ALOGV("writerTask poll() got %d events.", eventsPolled);
        if (eventsPolled == 0) {
            continue;
        }
        pthread_mutex_lock(&queue_mutex);
        queue->markAsWritten(eventsPolled);
        ALOGV("writerTask wrote %d events", eventsPolled);
        if (waiting_for_data) {
            ALOGV("writerTask - broadcast data_available_cond");
            pthread_cond_broadcast(&data_available_cond);
        }
        pthread_mutex_unlock(&queue_mutex);
    }
    // never actually returns
    return NULL;
}

/*
 * Cache of all sensors, with original handles replaced by global handles.
 * This will be handled to get_sensors_list() callers.
 */
static struct sensor_t const* global_sensors_list = NULL;
static int global_sensors_count = -1;

/*
 * Extends a sensors_poll_device_1 by including all the sub-module's devices.
 */
struct sensors_poll_context_t {
    /*
     * This is the device that SensorDevice.cpp uses to make API calls
     * to the multihal, which fans them out to sub-HALs.
     */
    sensors_poll_device_1 proxy_device; // must be first

    void addSubHwDevice(struct hw_device_t*);

    int activate(int handle, int enabled);
    int setDelay(int handle, int64_t ns);
    int poll(sensors_event_t* data, int count);
    int batch(int handle, int flags, int64_t period_ns, int64_t timeout);
    int flush(int handle);
    int close();

    std::vector<hw_device_t*> sub_hw_devices;
    std::vector<SensorEventQueue*> queues;
    std::vector<pthread_t> threads;
    int nextReadIndex;

    sensors_poll_device_t* get_v0_device_by_handle(int global_handle);
    sensors_poll_device_1_t* get_v1_device_by_handle(int global_handle);
    int get_device_version_by_handle(int global_handle);

    void copy_event_remap_handle(sensors_event_t* src, sensors_event_t* dest, int sub_index);
};

void sensors_poll_context_t::addSubHwDevice(struct hw_device_t* sub_hw_device) {
    ALOGV("addSubHwDevice");
    this->sub_hw_devices.push_back(sub_hw_device);

    SensorEventQueue *queue = new SensorEventQueue(SENSOR_EVENT_QUEUE_CAPACITY);
    this->queues.push_back(queue);

    TaskContext* taskContext = new TaskContext();
    taskContext->device = (sensors_poll_device_t*) sub_hw_device;
    taskContext->queue = queue;

    pthread_t writerThread;
    pthread_create(&writerThread, NULL, writerTask, taskContext);
    this->threads.push_back(writerThread);
}

sensors_poll_device_t* sensors_poll_context_t::get_v0_device_by_handle(int handle) {
    int sub_index = get_module_index(handle);
    return (sensors_poll_device_t*) this->sub_hw_devices[sub_index];
}

sensors_poll_device_1_t* sensors_poll_context_t::get_v1_device_by_handle(int handle) {
    int sub_index = get_module_index(handle);
    return (sensors_poll_device_1_t*) this->sub_hw_devices[sub_index];
}

int sensors_poll_context_t::get_device_version_by_handle(int handle) {
    sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
    return v0->common.version;
}

int sensors_poll_context_t::activate(int handle, int enabled) {
    int retval = -EINVAL;
    ALOGV("activate");
    sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
    if (v0)
        retval = v0->activate(v0, get_local_handle(handle), enabled);
    ALOGV("retval %d", retval);
    return retval;
}

int sensors_poll_context_t::setDelay(int handle, int64_t ns) {
    ALOGV("setDelay");
    sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
    int retval = v0->setDelay(v0, get_local_handle(handle), ns);
    ALOGV("retval %d", retval);
    return retval;
}

void sensors_poll_context_t::copy_event_remap_handle(sensors_event_t* dest, sensors_event_t* src,
        int sub_index) {
    memcpy(dest, src, sizeof(struct sensors_event_t));
    // A normal event's "sensor" field is a local handle. Convert it to a global handle.
    // A meta-data event must have its sensor set to 0, but it has a nested event
    // with a local handle that needs to be converted to a global handle.
    FullHandle full_handle;
    full_handle.moduleIndex = sub_index;
    // If it's a metadata event, rewrite the inner payload, not the sensor field.
    if (dest->type == SENSOR_TYPE_META_DATA) {
        full_handle.localHandle = dest->meta_data.sensor;
        dest->meta_data.sensor = full_to_global[full_handle];
    } else {
        full_handle.localHandle = dest->sensor;
        dest->sensor = full_to_global[full_handle];
    }
}

int sensors_poll_context_t::poll(sensors_event_t *data, int maxReads) {
    ALOGV("poll");
    int empties = 0;
    int queueCount = (int)this->queues.size();
    int eventsRead = 0;

    pthread_mutex_lock(&queue_mutex);
    while (eventsRead == 0) {
        while (empties < queueCount && eventsRead < maxReads) {
            SensorEventQueue* queue = this->queues.at(this->nextReadIndex);
            sensors_event_t* event = queue->peek();
            if (event == NULL) {
                empties++;
            } else {
                empties = 0;
                this->copy_event_remap_handle(&data[eventsRead++], event, nextReadIndex);
                queue->dequeue();
            }
            this->nextReadIndex = (this->nextReadIndex + 1) % queueCount;
        }
        if (eventsRead == 0) {
            // The queues have been scanned and none contain data, so wait.
            ALOGV("poll stopping to wait for data");
            waiting_for_data = true;
            pthread_cond_wait(&data_available_cond, &queue_mutex);
            waiting_for_data = false;
            empties = 0;
        }
    }
    pthread_mutex_unlock(&queue_mutex);
    ALOGV("poll returning %d events.", eventsRead);

    return eventsRead;
}

int sensors_poll_context_t::batch(int handle, int flags, int64_t period_ns, int64_t timeout) {
    ALOGV("batch");
    int retval = -EINVAL;
    int version = this->get_device_version_by_handle(handle);
    if (version >= SENSORS_DEVICE_API_VERSION_1_0) {
        sensors_poll_device_1_t* v1 = this->get_v1_device_by_handle(handle);
        retval = v1->batch(v1, get_local_handle(handle), flags, period_ns, timeout);
    }
    ALOGV("retval %d", retval);
    return retval;
}

int sensors_poll_context_t::flush(int handle) {
    ALOGV("flush");
    int retval = -EINVAL;
    int version = this->get_device_version_by_handle(handle);
    if (version >= SENSORS_DEVICE_API_VERSION_1_0) {
        sensors_poll_device_1_t* v1 = this->get_v1_device_by_handle(handle);
        retval = v1->flush(v1, get_local_handle(handle));
    }
    ALOGV("retval %d", retval);
    return retval;
}

int sensors_poll_context_t::close() {
    ALOGV("close");
    for (std::vector<hw_device_t*>::iterator it = this->sub_hw_devices.begin();
            it != this->sub_hw_devices.end(); it++) {
        hw_device_t* dev = *it;
        int retval = dev->close(dev);
        ALOGV("retval %d", retval);
    }
    return 0;
}


static int device__close(struct hw_device_t *dev) {
    sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
    if (ctx != NULL) {
        int retval = ctx->close();
        delete ctx;
    }
    return 0;
}

static int device__activate(struct sensors_poll_device_t *dev, int handle,
        int enabled) {
    sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
    return ctx->activate(handle, enabled);
}

static int device__setDelay(struct sensors_poll_device_t *dev, int handle,
        int64_t ns) {
    sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
    return ctx->setDelay(handle, ns);
}

static int device__poll(struct sensors_poll_device_t *dev, sensors_event_t* data,
        int count) {
    sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
    return ctx->poll(data, count);
}

static int device__batch(struct sensors_poll_device_1 *dev, int handle,
        int flags, int64_t period_ns, int64_t timeout) {
    sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
    return ctx->batch(handle, flags, period_ns, timeout);
}

static int device__flush(struct sensors_poll_device_1 *dev, int handle) {
    sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
    return ctx->flush(handle);
}

static int open_sensors(const struct hw_module_t* module, const char* name,
        struct hw_device_t** device);

static bool starts_with(const char* s, const char* prefix) {
    if (s == NULL || prefix == NULL) {
        return false;
    }
    size_t s_size = strlen(s);
    size_t prefix_size = strlen(prefix);
    return s_size >= prefix_size && strncmp(s, prefix, prefix_size) == 0;
}

/*
 * Adds valid paths from the config file to the vector passed in.
 * The vector must not be null.
 */
static void get_so_paths(std::vector<char*> *so_paths) {
    FILE *conf_file = fopen(CONFIG_FILENAME, "r");
    if (conf_file == NULL) {
        ALOGW("No multihal config file found at %s", CONFIG_FILENAME);
        return;
    }
    ALOGI("Multihal config file found at %s", CONFIG_FILENAME);
    char *line = NULL;
    size_t len = 0;
    int line_count = 0;
    while (getline(&line, &len, conf_file) != -1) {
        // overwrite trailing eoln with null char
        char* pch = strchr(line, '\n');
        if (pch != NULL) {
            *pch = '\0';
        }
        ALOGV("config file line #%d: '%s'", ++line_count, line);
        char *real_path = realpath(line, NULL);
        if (starts_with(real_path, LEGAL_SUBHAL_PATH_PREFIX)) {
            ALOGI("accepting valid path '%s'", real_path);
            char* compact_line = new char[strlen(real_path) + 1];
            strcpy(compact_line, real_path);
            so_paths->push_back(compact_line);
        } else {
            ALOGW("rejecting path '%s' because it does not start with '%s'",
                    real_path, LEGAL_SUBHAL_PATH_PREFIX);
        }
        free(real_path);
    }
    free(line);
    fclose(conf_file);
    ALOGV("hals.conf contained %d lines", line_count);
}

/*
 * Ensures that the sub-module array is initialized.
 * This can be first called from get_sensors_list or from open_sensors.
 */
static void lazy_init_modules() {
    pthread_mutex_lock(&init_modules_mutex);
    if (sub_hw_modules != NULL) {
        pthread_mutex_unlock(&init_modules_mutex);
        return;
    }
    std::vector<char*> *so_paths = new std::vector<char*>();
    get_so_paths(so_paths);

    // dlopen the module files and cache their module symbols in sub_hw_modules
    sub_hw_modules = new std::vector<hw_module_t *>();
    dlerror(); // clear any old errors
    const char* sym = HAL_MODULE_INFO_SYM_AS_STR;
    for (std::vector<char*>::iterator it = so_paths->begin(); it != so_paths->end(); it++) {
        char* path = *it;
        void* lib_handle = dlopen(path, RTLD_LAZY);
        if (lib_handle == NULL) {
            ALOGW("dlerror(): %s", dlerror());
        } else {
            ALOGI("hal lib was loaded: %s", path);
            ALOGV("Opening symbol \"%s\"", sym);
            // clear old errors
            dlerror();
            struct hw_module_t* module = (hw_module_t*) dlsym(lib_handle, sym);
            const char* error;
            if ((error = dlerror()) != NULL) {
                ALOGW("Error calling dlsym: %s", error);
            } else if (module == NULL) {
                ALOGW("module == NULL");
            } else {
                ALOGI("OK, dlsym()'ed \"%s\"", sym);
                sub_hw_modules->push_back(module);
            }
        }
    }
    pthread_mutex_unlock(&init_modules_mutex);
}

/*
 * Lazy-initializes global_sensors_count, global_sensors_list, and module_sensor_handles.
 */
static void lazy_init_sensors_list() {
    ALOGV("lazy_init_sensors_list");
    pthread_mutex_lock(&init_sensors_mutex);
    if (global_sensors_list != NULL) {
        // already initialized
        pthread_mutex_unlock(&init_sensors_mutex);
        ALOGV("lazy_init_sensors_list - early return");
        return;
    }

    ALOGV("lazy_init_sensors_list needs to do work");
    lazy_init_modules();

    // Count all the sensors, then allocate an array of blanks.
    global_sensors_count = 0;
    const struct sensor_t *subhal_sensors_list;
    for (std::vector<hw_module_t*>::iterator it = sub_hw_modules->begin();
            it != sub_hw_modules->end(); it++) {
        struct sensors_module_t *module = (struct sensors_module_t*) *it;
        global_sensors_count += module->get_sensors_list(module, &subhal_sensors_list);
        ALOGV("increased global_sensors_count to %d", global_sensors_count);
    }

    // The global_sensors_list is full of consts.
    // Manipulate this non-const list, and point the const one to it when we're done.
    sensor_t* mutable_sensor_list = new sensor_t[global_sensors_count];

    // index of the next sensor to set in mutable_sensor_list
    int mutable_sensor_index = 0;
    int module_index = 0;

    for (std::vector<hw_module_t*>::iterator it = sub_hw_modules->begin();
            it != sub_hw_modules->end(); it++) {
        hw_module_t *hw_module = *it;
        ALOGV("examine one module");
        // Read the sub-module's sensor list.
        struct sensors_module_t *module = (struct sensors_module_t*) hw_module;
        int module_sensor_count = module->get_sensors_list(module, &subhal_sensors_list);
        ALOGV("the module has %d sensors", module_sensor_count);

        // Copy the HAL's sensor list into global_sensors_list,
        // with the handle changed to be a global handle.
        for (int i = 0; i < module_sensor_count; i++) {
            ALOGV("examining one sensor");
            const struct sensor_t *local_sensor = &subhal_sensors_list[i];
            int local_handle = local_sensor->handle;
            memcpy(&mutable_sensor_list[mutable_sensor_index], local_sensor,
                sizeof(struct sensor_t));

            // Overwrite the global version's handle with a global handle.
            int global_handle = assign_global_handle(module_index, local_handle);

            mutable_sensor_list[mutable_sensor_index].handle = global_handle;
            ALOGI("module_index %d, local_handle %d, global_handle %d",
                    module_index, local_handle, global_handle);

            mutable_sensor_index++;
        }
        module_index++;
    }
    // Set the const static global_sensors_list to the mutable one allocated by this function.
    global_sensors_list = mutable_sensor_list;

    pthread_mutex_unlock(&init_sensors_mutex);
    ALOGV("end lazy_init_sensors_list");
}

static int module__get_sensors_list(struct sensors_module_t* module,
        struct sensor_t const** list) {
    ALOGV("module__get_sensors_list start");
    lazy_init_sensors_list();
    *list = global_sensors_list;
    ALOGV("global_sensors_count: %d", global_sensors_count);
    for (int i = 0; i < global_sensors_count; i++) {
        ALOGV("sensor type: %d", global_sensors_list[i].type);
    }
    return global_sensors_count;
}

static struct hw_module_methods_t sensors_module_methods = {
    open : open_sensors
};

struct sensors_module_t HAL_MODULE_INFO_SYM = {
    common :{
        tag : HARDWARE_MODULE_TAG,
        version_major : 1,
        version_minor : 0,
        id : SENSORS_HARDWARE_MODULE_ID,
        name : "MultiHal Sensor Module",
        author : "Google, Inc",
        methods : &sensors_module_methods,
        dso : NULL,
        reserved : {0},
    },
    get_sensors_list : module__get_sensors_list
};

static int open_sensors(const struct hw_module_t* hw_module, const char* name,
        struct hw_device_t** hw_device_out) {
    ALOGI("open_sensors begin...");

    lazy_init_modules();

    // Create proxy device, to return later.
    sensors_poll_context_t *dev = new sensors_poll_context_t();
    memset(dev, 0, sizeof(sensors_poll_device_1_t));
    dev->proxy_device.common.tag = HARDWARE_DEVICE_TAG;
    dev->proxy_device.common.version = SENSORS_DEVICE_API_VERSION_1_0;
    dev->proxy_device.common.module = const_cast<hw_module_t*>(hw_module);
    dev->proxy_device.common.close = device__close;
    dev->proxy_device.activate = device__activate;
    dev->proxy_device.setDelay = device__setDelay;
    dev->proxy_device.poll = device__poll;
    dev->proxy_device.batch = device__batch;
    dev->proxy_device.flush = device__flush;

    dev->nextReadIndex = 0;

    // Open() the subhal modules. Remember their devices in a vector parallel to sub_hw_modules.
    for (std::vector<hw_module_t*>::iterator it = sub_hw_modules->begin();
            it != sub_hw_modules->end(); it++) {
        sensors_module_t *sensors_module = (sensors_module_t*) *it;
        struct hw_device_t* sub_hw_device;
        int sub_open_result = sensors_module->common.methods->open(*it, name, &sub_hw_device);
        if (!sub_open_result)
            dev->addSubHwDevice(sub_hw_device);
    }

    // Prepare the output param and return
    *hw_device_out = &dev->proxy_device.common;
    ALOGI("...open_sensors end");
    return 0;
}
