/*
 * Copyright (C) 2008 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_TAG "Sensors"

#include <hardware/sensors.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <math.h>
#include <poll.h>
#include <pthread.h>
#include <stdlib.h>
#include <linux/input.h>
#include <utils/Atomic.h>
#include <utils/Log.h>

#include "sensors.h"
#include "AccelSensor.h"
#include "LightSensor.h"
#include "ProximitySensor.h"
#include "AkmSensor.h"
#include "GyroSensor.h"
#include "PressureSensor.h"

/*****************************************************************************/
static struct sensor_t sensor_list[MAX_SENSORS];
static char name[MAX_SENSORS][SYSFS_MAXLEN];
static char vendor[MAX_SENSORS][SYSFS_MAXLEN];
static int dynamic_sensor_number;

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

static int get_node(char *buf, char *path) {
	char * fret;
	int len = 0;
	FILE * fd;

	if (NULL == buf || NULL == path)
		return -1;

	fd = fopen(path, "r");
	if (NULL == fd)
		return -1;

	fret = fgets(buf,SYSFS_MAXLEN,fd);
	if (NULL == fret) {
		fclose(fd);
		return -1;
	}

	len = strlen(buf);

	if (buf[len - 1] == '\n')
		buf[len - 1] = '\0';

	fclose(fd);
	return 0;
}

static int get_sensors_list() {
	int number = 0;
	int fd = -1;
	int err = -1;
	const char *dirname = SYSFS_CLASS;
	char devname[PATH_MAX];
	char *filename;
	char *nodename;
	DIR *dir;
	struct dirent *de;
	char tempname[SYSFS_MAXLEN];

	dir = opendir(dirname);
	if(dir == NULL) {
		dynamic_sensor_number = 0;
		return -1;
	}
	strlcpy(devname, dirname, PATH_MAX - SYSFS_MAXLEN * 2 - 2);
	filename = devname + strlen(devname);
	*filename++ = '/';

	while((de = readdir(dir))) {
		if(de->d_name[0] == '.' &&
			(de->d_name[1] == '\0' ||
				(de->d_name[1] == '.' && de->d_name[2] == '\0')))
			continue;

		strlcpy(filename, de->d_name, SYSFS_MAXLEN);
		nodename = filename + strlen(de->d_name);
		*nodename++ = '/';

		strlcpy(nodename, SYSFS_NAME, SYSFS_MAXLEN);
		err = get_node(name[number], devname);
		if(err < 0)
			goto error;
		sensor_list[number].name = name[number];

		strlcpy(nodename, SYSFS_VENDOR, SYSFS_MAXLEN);
		err = get_node(vendor[number], devname);
		if(err < 0)
			goto error;
		sensor_list[number].vendor = vendor[number];

		strlcpy(nodename, SYSFS_VERSION, SYSFS_MAXLEN);
		err = get_node(tempname, devname);
		if(err < 0)
			goto error;
		sensor_list[number].version = atoi(tempname);

		strlcpy(nodename, SYSFS_HANDLE, SYSFS_MAXLEN);
		err = get_node(tempname, devname);
		if(err < 0)
			goto error;
		sensor_list[number].handle = atoi(tempname);

		strlcpy(nodename, SYSFS_TYPE, SYSFS_MAXLEN);
		err = get_node(tempname, devname);
		if(err < 0)
			goto error;
		sensor_list[number].type = atoi(tempname);

		strlcpy(nodename, SYSFS_MAXRANGE, SYSFS_MAXLEN);
		err = get_node(tempname, devname);
		if(err < 0)
			goto error;
		sensor_list[number].maxRange = atof(tempname);

		strlcpy(nodename, SYSFS_RESOLUTION, SYSFS_MAXLEN);
		err = get_node(tempname, devname);
		if(err < 0)
			goto error;
		sensor_list[number].resolution = atof(tempname);

		strlcpy(nodename, SYSFS_POWER, SYSFS_MAXLEN);
		err = get_node(tempname, devname);
		if(err < 0)
			goto error;
		sensor_list[number].power = atof(tempname);

		strlcpy(nodename, SYSFS_MINDELAY, SYSFS_MAXLEN);
		err = get_node(tempname, devname);
		if(err < 0)
			goto error;
		sensor_list[number].minDelay = atoi(tempname);

		number++;
	}
	closedir(dir);
	dynamic_sensor_number = number;
	return number;

error:
	dynamic_sensor_number = 0;
	closedir(dir);
	ALOGE("get_sensors_list failed!");
	return -1;
}

static int sensors__get_sensors_list(struct sensors_module_t* module,
								 struct sensor_t const** list)
{
	if(dynamic_sensor_number > 0) {
		*list = sensor_list;
		return dynamic_sensor_number;
	} else { /* If we could not find any sensor folder, load the default.*/
		ALOGE("no list:get_sensors_list failed!");
		return 0;
	}
}

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: "Quic Sensor module",
				author: "Quic",
				methods: &sensors_module_methods,
		},
		get_sensors_list: sensors__get_sensors_list,
};

struct sensors_poll_context_t {
	struct sensors_poll_device_t device; // must be first

		sensors_poll_context_t();
		~sensors_poll_context_t();
	int activate(int handle, int enabled);
	int setDelay(int handle, int64_t ns);
	int pollEvents(sensors_event_t* data, int count);

private:
	int light;
	int proximity;
	int compass;
	int gyro;
	int accel;
	int pressure;
	static const size_t wake = MAX_SENSORS;
	static const char WAKE_MESSAGE = 'W';
	struct pollfd mPollFds[MAX_SENSORS+1];
	int mWritePipeFd;
	int device_id;
	SensorBase* mSensors[MAX_SENSORS];

	int handleToDriver(int handle) const {
		switch (handle) {
			case SENSORS_ACCELERATION_HANDLE:
				return accel;
			case SENSORS_MAGNETIC_FIELD_HANDLE:
			case SENSORS_ORIENTATION_HANDLE:
				return compass;
			case SENSORS_PROXIMITY_HANDLE:
				return proximity;
			case SENSORS_LIGHT_HANDLE:
				return light;
			case SENSORS_GYROSCOPE_HANDLE:
				return gyro;
			case SENSORS_PRESSURE_HANDLE:
				return pressure;
		}
		return -EINVAL;
	}
};

/*****************************************************************************/

sensors_poll_context_t::sensors_poll_context_t()
{
	int number;
	int handle;
	light = -1;
	proximity = -1;
	compass = -1;
	gyro = -1;
	accel = -1;
	pressure = -1;
	device_id = 0;
	number = get_sensors_list();

	if(number <= 0){ /* use the static sensor list */
		light = 0;
		proximity = 1;
		compass = 2;
		gyro = 3;
		accel = 4;
		pressure = 5;
		device_id = 6;

		mSensors[light] = new LightSensor();
		mPollFds[light].fd = mSensors[light]->getFd();
		mPollFds[light].events = POLLIN;
		mPollFds[light].revents = 0;

		mSensors[proximity] = new ProximitySensor();
		mPollFds[proximity].fd = mSensors[proximity]->getFd();
		mPollFds[proximity].events = POLLIN;
		mPollFds[proximity].revents = 0;

#if 0
		mSensors[compass] = new AkmSensor();
		mPollFds[compass].fd = mSensors[compass]->getFd();
		mPollFds[compass].events = POLLIN;
		mPollFds[compass].revents = 0;
#endif

		mSensors[gyro] = new GyroSensor();
		mPollFds[gyro].fd = mSensors[gyro]->getFd();
		mPollFds[gyro].events = POLLIN;
		mPollFds[gyro].revents = 0;

		mSensors[accel] = new AccelSensor();
		mPollFds[accel].fd = mSensors[accel]->getFd();
		mPollFds[accel].events = POLLIN;
		mPollFds[accel].revents = 0;

		mSensors[pressure] = new PressureSensor();
		mPollFds[pressure].fd = mSensors[pressure]->getFd();
		mPollFds[pressure].events = POLLIN;
		mPollFds[pressure].revents = 0;

	} else { /* use the dynamic sensor list */
		for (handle = 0; handle < number; handle++) {
			switch (sensor_list[handle].handle) {
				case SENSORS_ACCELERATION_HANDLE:
				mSensors[device_id] = new AccelSensor(name[handle]);
				mPollFds[device_id].fd = mSensors[device_id]->getFd();
				mPollFds[device_id].events = POLLIN;
				mPollFds[device_id].revents = 0;
				accel = device_id;
				break;
#if 0
				case SENSORS_MAGNETIC_FIELD_HANDLE:
				mSensors[device_id] = new AkmSensor();
				mPollFds[device_id].fd = mSensors[device_id]->getFd();
				mPollFds[device_id].events = POLLIN;
				mPollFds[device_id].revents = 0;
				compass = device_id;
				break;
#endif
				case SENSORS_PROXIMITY_HANDLE:
				mSensors[device_id] = new ProximitySensor(name[handle]);
				mPollFds[device_id].fd = mSensors[device_id]->getFd();
				mPollFds[device_id].events = POLLIN;
				mPollFds[device_id].revents = 0;
				proximity = device_id;
				break;

				case SENSORS_LIGHT_HANDLE:
				mSensors[device_id] = new LightSensor(name[handle]);
				mPollFds[device_id].fd = mSensors[device_id]->getFd();
				mPollFds[device_id].events = POLLIN;
				mPollFds[device_id].revents = 0;
				light = device_id;
				break;

				case SENSORS_GYROSCOPE_HANDLE:
				mSensors[device_id] = new GyroSensor(name[handle]);
				mPollFds[device_id].fd = mSensors[device_id]->getFd();
				mPollFds[device_id].events = POLLIN;
				mPollFds[device_id].revents = 0;
				gyro = device_id;
				break;

				case SENSORS_PRESSURE_HANDLE:
				mSensors[device_id] = new PressureSensor(name[handle]);
				mPollFds[device_id].fd = mSensors[device_id]->getFd();
				mPollFds[device_id].events = POLLIN;
				mPollFds[device_id].revents = 0;
				pressure = device_id;
				break;

				default:
				ALOGE("No handle %d for this type sensor!",handle);
				device_id--;
			}
			device_id++;
		}
	}
	ALOGI("The avaliable sensor handle number is %d",device_id);
	int wakeFds[2];
	int result = pipe(wakeFds);
	ALOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno));
	fcntl(wakeFds[0], F_SETFL, O_NONBLOCK);
	fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);
	mWritePipeFd = wakeFds[1];

	mPollFds[device_id].fd = wakeFds[0];
	mPollFds[device_id].events = POLLIN;
	mPollFds[device_id].revents = 0;
}

sensors_poll_context_t::~sensors_poll_context_t() {
	for (int i=0 ; i<device_id ; i++) {
		delete mSensors[i];
	}
	close(mPollFds[device_id].fd);
	close(mWritePipeFd);
}

int sensors_poll_context_t::activate(int handle, int enabled) {
	int index = handleToDriver(handle);
	if (index < 0) return index;
	int err =  mSensors[index]->enable(handle, enabled);
	if (enabled && !err) {
		const char wakeMessage(WAKE_MESSAGE);
		int result = write(mWritePipeFd, &wakeMessage, 1);
		ALOGE_IF(result<0, "error sending wake message (%s)", strerror(errno));
	}
	return err;
}

int sensors_poll_context_t::setDelay(int handle, int64_t ns) {

	int index = handleToDriver(handle);
	if (index < 0) return index;
	return mSensors[index]->setDelay(handle, ns);
}

int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
{
	int nbEvents = 0;
	int n = 0;

	do {
		// see if we have some leftover from the last poll()
		for (int i=0 ; count && i<device_id ; i++) {
			SensorBase* const sensor(mSensors[i]);
			if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())) {
				int nb = sensor->readEvents(data, count);
				if (nb < count) {
					// no more data for this sensor
					mPollFds[i].revents = 0;
				}
				count -= nb;
				nbEvents += nb;
				data += nb;
			}
		}

		if (count) {
			// we still have some room, so try to see if we can get
			// some events immediately or just wait if we don't have
			// anything to return
			do {
				n = poll(mPollFds, device_id+1, nbEvents ? 0 : -1);
			} while (n < 0 && errno == EINTR);
			if (n<0) {
				ALOGE("poll() failed (%s)", strerror(errno));
				return -errno;
			}
			if (mPollFds[device_id].revents & POLLIN) {
				char msg;
				int result = read(mPollFds[device_id].fd, &msg, 1);
				ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno));
				ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg));
				mPollFds[device_id].revents = 0;
			}
		}
		// if we have events and space, go read them
	} while (n && count);

	return nbEvents;
}

/*****************************************************************************/

static int poll__close(struct hw_device_t *dev)
{
	sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
	if (ctx) {
		delete ctx;
	}
	return 0;
}

static int poll__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 poll__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 poll__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->pollEvents(data, count);
}

/*****************************************************************************/

/** Open a new instance of a sensor device using name */
static int open_sensors(const struct hw_module_t* module, const char* id,
						struct hw_device_t** device)
{
		int status = -EINVAL;
		sensors_poll_context_t *dev = new sensors_poll_context_t();

		memset(&dev->device, 0, sizeof(sensors_poll_device_t));

		dev->device.common.tag = HARDWARE_DEVICE_TAG;
		dev->device.common.version  = 0;
		dev->device.common.module   = const_cast<hw_module_t*>(module);
		dev->device.common.close	= poll__close;
		dev->device.activate		= poll__activate;
		dev->device.setDelay		= poll__setDelay;
		dev->device.poll			= poll__poll;

		*device = &dev->device.common;
		status = 0;

		return status;
}

