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

		if (m_outputReportSize < HID_RMI4_READ_OUTPUT_COUNT + 2) {
			return -1;
		}
		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) {
				if (static_cast<ssize_t>(m_inputReportSize) <
				    std::max(HID_RMI4_READ_INPUT_COUNT,
					     HID_RMI4_READ_INPUT_DATA))
					return -1;
				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;

	if (static_cast<ssize_t>(m_outputReportSize) <
	    HID_RMI4_WRITE_OUTPUT_DATA + len)
		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;
	unsigned 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) {
					if (bytes > m_inputReportSize ||
					    m_inputReportSize < HID_RMI4_ATTN_INTERUPT_SOURCES + 1)
						return -1;
					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;

	if (m_inputReportSize < HID_RMI4_REPORT_ID + 1)
		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) {
		if (static_cast<ssize_t>(m_inputReportSize) < count)
			return -1;
		memcpy(m_attnData, m_inputReport, count /*offset?*/);
	} else if (m_inputReport[HID_RMI4_REPORT_ID] == RMI_READ_DATA_REPORT_ID) {
		if (static_cast<ssize_t>(m_inputReportSize) < count)
			return -1;
		memcpy(m_readData, m_inputReport, count /*offset?*/);
		m_dataBytesRead = count /*offset?*/;
	}
	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;
}
