/*
 * Copyright (C) 2014 Andrew Duggan
 * Copyright (C) 2014 Synaptics Inc
 *
 * 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 <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/select.h>

#include <linux/types.h>
#include <linux/input.h>
#include <linux/hidraw.h>
#include <signal.h>
#include <stdlib.h>

#include "hiddevice.h"

#define RMI_WRITE_REPORT_ID                 0x9 // Output Report
#define RMI_READ_ADDR_REPORT_ID             0xa // Output Report
#define RMI_READ_DATA_REPORT_ID             0xb // Input Report
#define RMI_ATTN_REPORT_ID                  0xc // Input Report
#define RMI_SET_RMI_MODE_REPORT_ID          0xf // Feature Report

enum rmi_hid_mode_type {
	HID_RMI4_MODE_MOUSE                     = 0,
	HID_RMI4_MODE_ATTN_REPORTS              = 1,
	HID_RMI4_MODE_NO_PACKED_ATTN_REPORTS    = 2,
};

enum hid_report_type {
	HID_REPORT_TYPE_UNKNOWN			= 0x0,
	HID_REPORT_TYPE_INPUT			= 0x81,
	HID_REPORT_TYPE_OUTPUT			= 0x91,
	HID_REPORT_TYPE_FEATURE			= 0xb1,
};

#define HID_RMI4_REPORT_ID			0
#define HID_RMI4_READ_INPUT_COUNT		1
#define HID_RMI4_READ_INPUT_DATA		2
#define HID_RMI4_READ_OUTPUT_ADDR		2
#define HID_RMI4_READ_OUTPUT_COUNT		4
#define HID_RMI4_WRITE_OUTPUT_COUNT		1
#define HID_RMI4_WRITE_OUTPUT_ADDR		2
#define HID_RMI4_WRITE_OUTPUT_DATA		4
#define HID_RMI4_FEATURE_MODE			1
#define HID_RMI4_ATTN_INTERUPT_SOURCES		1
#define HID_RMI4_ATTN_DATA			2

#define SYNAPTICS_VENDOR_ID			0x06cb

int HIDDevice::Open(const char * filename)
{
	int rc;
	int desc_size;

	if (!filename)
		return -EINVAL;

	m_fd = open(filename, O_RDWR);
	if (m_fd < 0)
		return -1;

	memset(&m_rptDesc, 0, sizeof(m_rptDesc));
	memset(&m_info, 0, sizeof(m_info));

	rc = ioctl(m_fd, HIDIOCGRDESCSIZE, &desc_size);
	if (rc < 0)
		return rc;
	
	m_rptDesc.size = desc_size;
	rc = ioctl(m_fd, HIDIOCGRDESC, &m_rptDesc);
	if (rc < 0)
		return rc;
	
	rc = ioctl(m_fd, HIDIOCGRAWINFO, &m_info);
	if (rc < 0)
		return rc;

	if (m_info.vendor != SYNAPTICS_VENDOR_ID) {
		errno = -ENODEV;
		return -1;
	}

	ParseReportSizes();

	m_inputReport = new unsigned char[m_inputReportSize]();
	if (!m_inputReport) {
		errno = -ENOMEM;
		return -1;
	}

	m_outputReport = new unsigned char[m_outputReportSize]();
	if (!m_outputReport) {
		errno = -ENOMEM;
		return -1;
	}

	m_readData = new unsigned char[m_inputReportSize]();
	if (!m_readData) {
		errno = -ENOMEM;
		return -1;
	}

	m_attnData = new unsigned char[m_inputReportSize]();
	if (!m_attnData) {
		errno = -ENOMEM;
		return -1;
	}

	m_deviceOpen = true;

	rc = SetMode(HID_RMI4_MODE_ATTN_REPORTS);
	if (rc)
		return -1;

	return 0;
}

void HIDDevice::ParseReportSizes()
{
	bool isVendorSpecific = false;
	bool isReport = false;
	int totalReportSize = 0;
	int reportSize = 0;
	int reportCount = 0;
	enum hid_report_type hidReportType = HID_REPORT_TYPE_UNKNOWN;

	for (unsigned int i = 0; i < m_rptDesc.size; ++i) {
		if (isVendorSpecific) {
			if (m_rptDesc.value[i] == 0x85 || m_rptDesc.value[i] == 0xc0) {
				if (isReport) {
					// finish up data on the previous report
					totalReportSize = (reportSize * reportCount) >> 3;

					switch (hidReportType) {
						case HID_REPORT_TYPE_INPUT:
							m_inputReportSize = totalReportSize + 1;
							break;
						case HID_REPORT_TYPE_OUTPUT:
							m_outputReportSize = totalReportSize + 1;
							break;
						case HID_REPORT_TYPE_FEATURE:
							m_featureReportSize = totalReportSize + 1;
							break;
						case HID_REPORT_TYPE_UNKNOWN:
						default:
							break;
					}
				}

				// reset values for the new report
				totalReportSize = 0;
				reportSize = 0;
				reportCount = 0;
				hidReportType = HID_REPORT_TYPE_UNKNOWN;

				if (m_rptDesc.value[i] == 0x85)
					isReport = true;
				else
					isReport = false;

				if (m_rptDesc.value[i] == 0xc0)
					isVendorSpecific = false;
			}

			if (isReport) {
				if (m_rptDesc.value[i] == 0x75) {
					reportSize = m_rptDesc.value[++i];
					continue;
				}

				if (m_rptDesc.value[i] == 0x95) {
					reportCount = m_rptDesc.value[++i];
					continue;
				}

				if (m_rptDesc.value[i] == HID_REPORT_TYPE_INPUT)
					hidReportType = HID_REPORT_TYPE_INPUT;

				if (m_rptDesc.value[i] == HID_REPORT_TYPE_OUTPUT)
					hidReportType = HID_REPORT_TYPE_OUTPUT;

				if (m_rptDesc.value[i] == HID_REPORT_TYPE_FEATURE) {
					hidReportType = HID_REPORT_TYPE_FEATURE;
				}
			}
		}

		if (m_rptDesc.value[i] == 0x06 && m_rptDesc.value[i + 1] == 0x00
						&& m_rptDesc.value[i + 2] == 0xFF) {
			isVendorSpecific = true;
			i += 2;
		}
	}
}

int HIDDevice::Read(unsigned short addr, unsigned char *buf, unsigned short len)
{
	ssize_t count;
	size_t bytesReadPerRequest;
	size_t bytesInDataReport;
	size_t totalBytesRead;
	size_t bytesPerRequest;
	size_t bytesWritten;
	size_t bytesToRequest;
	int reportId;
	int rc;

	if (!m_deviceOpen)
		return -1;

	if (m_bytesPerReadRequest)
		bytesPerRequest = m_bytesPerReadRequest;
	else
		bytesPerRequest = len;

	for (totalBytesRead = 0; totalBytesRead < len; totalBytesRead += bytesReadPerRequest) {
		count = 0;
		if ((len - totalBytesRead) < bytesPerRequest)
			bytesToRequest = len % bytesPerRequest;
		else
			bytesToRequest = bytesPerRequest;

		m_outputReport[HID_RMI4_REPORT_ID] = RMI_READ_ADDR_REPORT_ID;
		m_outputReport[1] = 0; /* old 1 byte read count */
		m_outputReport[HID_RMI4_READ_OUTPUT_ADDR] = addr & 0xFF;
		m_outputReport[HID_RMI4_READ_OUTPUT_ADDR + 1] = (addr >> 8) & 0xFF;
		m_outputReport[HID_RMI4_READ_OUTPUT_COUNT] = bytesToRequest  & 0xFF;
		m_outputReport[HID_RMI4_READ_OUTPUT_COUNT + 1] = (bytesToRequest >> 8) & 0xFF;

		m_dataBytesRead = 0;

		for (bytesWritten = 0; bytesWritten < m_outputReportSize; bytesWritten += count) {
			m_bCancel = false;
			count = write(m_fd, m_outputReport + bytesWritten,
					m_outputReportSize - bytesWritten);
			if (count < 0) {
				if (errno == EINTR && m_deviceOpen && !m_bCancel)
					continue;
				else
					return count;
			}
			break;
		}

		bytesReadPerRequest = 0;
		while (bytesReadPerRequest < bytesToRequest) {
			rc = GetReport(&reportId);
			if (rc > 0 && reportId == RMI_READ_DATA_REPORT_ID) {
				bytesInDataReport = m_readData[HID_RMI4_READ_INPUT_COUNT];
				memcpy(buf + bytesReadPerRequest, &m_readData[HID_RMI4_READ_INPUT_DATA],
					bytesInDataReport);
				bytesReadPerRequest += bytesInDataReport;
				m_dataBytesRead = 0;
			}
		}
		addr += bytesPerRequest;
	}

	return totalBytesRead;
}

int HIDDevice::Write(unsigned short addr, const unsigned char *buf, unsigned short len)
{
	ssize_t count;

	if (!m_deviceOpen)
		return -1;

	m_outputReport[HID_RMI4_REPORT_ID] = RMI_WRITE_REPORT_ID;
	m_outputReport[HID_RMI4_WRITE_OUTPUT_COUNT] = len;
	m_outputReport[HID_RMI4_WRITE_OUTPUT_ADDR] = addr & 0xFF;
	m_outputReport[HID_RMI4_WRITE_OUTPUT_ADDR + 1] = (addr >> 8) & 0xFF;
	memcpy(&m_outputReport[HID_RMI4_WRITE_OUTPUT_DATA], buf, len);

	for (;;) {
		m_bCancel = false;
		count = write(m_fd, m_outputReport, m_outputReportSize);
		if (count < 0) {
			if (errno == EINTR && m_deviceOpen && !m_bCancel)
				continue;
			else
				return count;
		}
		return count;
	}
}

int HIDDevice::SetMode(int mode)
{
	int rc;
	char buf[2];

	if (!m_deviceOpen)
		return -1;

	buf[0] = 0xF;
	buf[1] = mode;
	rc = ioctl(m_fd, HIDIOCSFEATURE(2), buf);
	if (rc < 0) {
		perror("HIDIOCSFEATURE");
		return rc;
	}

	return 0;
}

void HIDDevice::Close()
{
	if (!m_deviceOpen)
		return;

	SetMode(HID_RMI4_MODE_MOUSE);
	m_deviceOpen = false;
	close(m_fd);
	m_fd = -1;

	delete[] m_inputReport;
	m_inputReport = NULL;
	delete[] m_outputReport;
	m_outputReport = NULL;
	delete[] m_readData;
	m_readData = NULL;
	delete[] m_attnData;
	m_attnData = NULL;
}

int HIDDevice::WaitForAttention(struct timeval * timeout, unsigned int source_mask)
{
	return GetAttentionReport(timeout, source_mask, NULL, NULL);
}

int HIDDevice::GetAttentionReport(struct timeval * timeout, unsigned int source_mask,
					unsigned char *buf, unsigned int *len)
{
	int rc = 0;
	int bytes = m_inputReportSize;
	int reportId;

	if (len && m_inputReportSize < *len) {
		bytes = *len;
		*len = m_inputReportSize;
	}

	// Assume the Linux implementation of select with timeout set to the
	// time remaining.
	while (!timeout || (timeout->tv_sec != 0 || timeout->tv_usec != 0)) {
		rc = GetReport(&reportId, timeout);
		if (rc > 0) {
			if (reportId == RMI_ATTN_REPORT_ID) {
				if (buf)
					memcpy(buf, m_attnData, bytes);
				if (source_mask & m_attnData[HID_RMI4_ATTN_INTERUPT_SOURCES])
					return rc;
			}
		} else {
			return rc;
		}
	}

	return rc;
}

int HIDDevice::GetReport(int *reportId, struct timeval * timeout)
{
	ssize_t count = 0;
	fd_set fds;
	int rc;

	if (!m_deviceOpen)
		return -1;

	for (;;) {
		FD_ZERO(&fds);
		FD_SET(m_fd, &fds);

		rc = select(m_fd + 1, &fds, NULL, NULL, timeout);
		if (rc == 0) {
			return -ETIMEDOUT;
		} else if (rc < 0) {
			if (errno == EINTR && m_deviceOpen && !m_bCancel)
				continue;
			else
				return rc;
		} else if (rc > 0 && FD_ISSET(m_fd, &fds)) {
			size_t offset = 0;
			for (;;) {
				m_bCancel = false;
				count = read(m_fd, m_inputReport + offset, m_inputReportSize - offset);
				if (count < 0) {
					if (errno == EINTR && m_deviceOpen && !m_bCancel)
						continue;
					else
						return count;
				}
				offset += count;
				if (offset == m_inputReportSize)
					break;
			}
		}
		break;
	}

	if (reportId)
		*reportId = m_inputReport[HID_RMI4_REPORT_ID];

	if (m_inputReport[HID_RMI4_REPORT_ID] == RMI_ATTN_REPORT_ID) {
		memcpy(m_attnData, m_inputReport, count);
	} else if (m_inputReport[HID_RMI4_REPORT_ID] == RMI_READ_DATA_REPORT_ID) {
		memcpy(m_readData, m_inputReport, count);
		m_dataBytesRead = count;
	}
	return 1;
}

void HIDDevice::PrintReport(const unsigned char *report)
{
	int i;
	int len = 0;
	const unsigned char * data;
	int addr = 0;

	switch (report[HID_RMI4_REPORT_ID]) {
		case RMI_WRITE_REPORT_ID:
			len = report[HID_RMI4_WRITE_OUTPUT_COUNT];
			data = &report[HID_RMI4_WRITE_OUTPUT_DATA];
			addr = (report[HID_RMI4_WRITE_OUTPUT_ADDR] & 0xFF)
				| ((report[HID_RMI4_WRITE_OUTPUT_ADDR + 1] & 0xFF) << 8);
			fprintf(stdout, "Write Report:\n");
			fprintf(stdout, "Address = 0x%02X\n", addr);
			fprintf(stdout, "Length = 0x%02X\n", len);
			break;
		case RMI_READ_ADDR_REPORT_ID:
			addr = (report[HID_RMI4_READ_OUTPUT_ADDR] & 0xFF)
				| ((report[HID_RMI4_READ_OUTPUT_ADDR + 1] & 0xFF) << 8);
			len = (report[HID_RMI4_READ_OUTPUT_COUNT] & 0xFF)
				| ((report[HID_RMI4_READ_OUTPUT_COUNT + 1] & 0xFF) << 8);
			fprintf(stdout, "Read Request (Output Report):\n");
			fprintf(stdout, "Address = 0x%02X\n", addr);
			fprintf(stdout, "Length = 0x%02X\n", len);
			return;
			break;
		case RMI_READ_DATA_REPORT_ID:
			len = report[HID_RMI4_READ_INPUT_COUNT];
			data = &report[HID_RMI4_READ_INPUT_DATA];
			fprintf(stdout, "Read Data Report:\n");
			fprintf(stdout, "Length = 0x%02X\n", len);
			break;
		case RMI_ATTN_REPORT_ID:
			fprintf(stdout, "Attention Report:\n");
			len = 28;
			data = &report[HID_RMI4_ATTN_DATA];
			fprintf(stdout, "Interrupt Sources: 0x%02X\n", 
				report[HID_RMI4_ATTN_INTERUPT_SOURCES]);
			break;
		default:
			fprintf(stderr, "Unknown Report: ID 0x%02x\n", report[HID_RMI4_REPORT_ID]);
			return;
	}

	fprintf(stdout, "Data:\n");
	for (i = 0; i < len; ++i) {
		fprintf(stdout, "0x%02X ", data[i]);
		if (i % 8 == 7) {
			fprintf(stdout, "\n");
		}
	}
	fprintf(stdout, "\n\n");
}

// Print protocol specific device information
void HIDDevice::PrintDeviceInfo()
{
	fprintf(stdout, "HID device info:\nBus: %s Vendor: 0x%04x Product: 0x%04x\n",
		m_info.bustype == BUS_I2C ? "I2C" : "USB", m_info.vendor, m_info.product);
	fprintf(stdout, "Report sizes: input: %ld output: %ld\n", (unsigned long)m_inputReportSize,
		(unsigned long)m_outputReportSize);
}

bool WriteDeviceNameToFile(const char * file, const char * str)
{
	int fd;
	ssize_t size;

	fd = open(file, O_WRONLY);
	if (fd < 0)
		return false;

	for (;;) {
		size = write(fd, str, 19);
		if (size < 0) {
			if (errno == EINTR)
				continue;

			return false;
		}
		break;
	}
	close(fd);

	return true;
}

void HIDDevice::RebindDriver()
{
	int bus = m_info.bustype;
	int vendor = m_info.vendor;
	int product = m_info.product;
	std::string hidDeviceName;
	std::string transportDeviceName;
	std::string driverPath;
	std::string bindFile;
	std::string unbindFile;
	std::string hidrawFile;

	Close();

	if (!LookupHidDeviceName(bus, vendor, product, hidDeviceName)) {
		fprintf(stderr, "Failed to find HID device name for the specified device: bus (0x%x) vendor: (0x%x) product: (0x%x)\n",
			bus, vendor, product);
		return;
	}

	if (!FindTransportDevice(bus, hidDeviceName, transportDeviceName, driverPath)) {
		fprintf(stderr, "Failed to find the transport device / driver for %s\n", hidDeviceName.c_str());
		return;
	}

	bindFile = driverPath + "bind";
	unbindFile = driverPath + "unbind";

	if (!WriteDeviceNameToFile(unbindFile.c_str(), transportDeviceName.c_str())) {
		fprintf(stderr, "Failed to unbind HID device %s: %s\n",
			transportDeviceName.c_str(), strerror(errno));
		return;
	}

	if (!WriteDeviceNameToFile(bindFile.c_str(), transportDeviceName.c_str())) {
		fprintf(stderr, "Failed to bind HID device %s: %s\n",
			transportDeviceName.c_str(), strerror(errno));
		return;
	}

	// The hid device id has changed since this is now a new hid device. Now we have to look up the new name.
	if (!LookupHidDeviceName(bus, vendor, product, hidDeviceName)) {
		fprintf(stderr, "Failed to find HID device name for the specified device: bus (0x%x) vendor: (0x%x) product: (0x%x)\n",
			bus, vendor, product);
		return;
	}

	if (!FindHidRawFile(hidDeviceName, hidrawFile)) {
		fprintf(stderr, "Failed to find the hidraw device file for %s\n", hidDeviceName.c_str());
		return;
	}

	Open(hidrawFile.c_str());
}

bool HIDDevice::FindTransportDevice(int bus, std::string & hidDeviceName,
			std::string & transportDeviceName, std::string & driverPath)
{
	std::string devicePrefix = "/sys/bus/";
	std::string devicePath;
	struct dirent * devicesDirEntry;
	DIR * devicesDir;
	struct dirent * devDirEntry;
	DIR * devDir;
	bool deviceFound = false;
	ssize_t sz;

	if (bus == BUS_I2C) {
		devicePrefix += "i2c/";
		driverPath = devicePrefix + "drivers/i2c_hid/";
	} else {
		devicePrefix += "usb/";
		driverPath = devicePrefix + "drivers/usbhid/";
	}
	devicePath = devicePrefix + "devices/";

	devicesDir = opendir(devicePath.c_str());
	if (!devicesDir)
		return false;

	while((devicesDirEntry = readdir(devicesDir)) != NULL) {
		if (devicesDirEntry->d_type != DT_LNK)
			continue;

		char buf[PATH_MAX];

		sz = readlinkat(dirfd(devicesDir), devicesDirEntry->d_name, buf, PATH_MAX);
		if (sz < 0)
			continue;

		buf[sz] = 0;

		std::string fullLinkPath = devicePath + buf;
		devDir = opendir(fullLinkPath.c_str());
		if (!devDir) {
			fprintf(stdout, "opendir failed\n");
			continue;
		}

		while ((devDirEntry = readdir(devDir)) != NULL) {
			if (!strcmp(devDirEntry->d_name, hidDeviceName.c_str())) {
				transportDeviceName = devicesDirEntry->d_name;
				deviceFound = true;
				break;
			}
		}
		closedir(devDir);

		if (deviceFound)
			break;
	}
	closedir(devicesDir);

	return deviceFound;
}

bool HIDDevice::LookupHidDeviceName(int bus, int vendorId, int productId, std::string & deviceName)
{
	bool ret = false;
	struct dirent * devDirEntry;
	DIR * devDir;
	char devicePrefix[15];

	snprintf(devicePrefix, 15, "%04X:%04X:%04X", bus, vendorId, productId);

	devDir = opendir("/sys/bus/hid/devices");
	if (!devDir)
		return false;

	while ((devDirEntry = readdir(devDir)) != NULL) {
		if (!strncmp(devDirEntry->d_name, devicePrefix, 14)) {
			deviceName = devDirEntry->d_name;
			ret = true;
			break;
		}
	}
	closedir(devDir);

	return ret;
}

bool HIDDevice::FindHidRawFile(std::string & deviceName, std::string & hidrawFile)
{
	bool ret = false;
	char hidrawDir[PATH_MAX];
	struct dirent * devDirEntry;
	DIR * devDir;

	snprintf(hidrawDir, PATH_MAX, "/sys/bus/hid/devices/%s/hidraw", deviceName.c_str());

	devDir = opendir(hidrawDir);
	if (!devDir)
		return false;

	while ((devDirEntry = readdir(devDir)) != NULL) {
		if (!strncmp(devDirEntry->d_name, "hidraw", 6)) {
			hidrawFile = std::string("/dev/") + devDirEntry->d_name;
			ret = true;
			break;
		}
	}
	closedir(devDir);

	return ret;
}