/*
 * This file is part of libgpiod.
 *
 * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at
 * your option) any later version.
 */

/* Low-level, core library code. */

#include <gpiod.h>

#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <poll.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>

enum {
	LINE_FREE = 0,
	LINE_REQUESTED_VALUES,
	LINE_REQUESTED_EVENTS,
};

struct gpiod_line {
	unsigned int offset;
	int direction;
	int active_state;
	bool used;
	bool open_source;
	bool open_drain;

	int state;
	bool up_to_date;

	struct gpiod_chip *chip;
	int fd;

	char name[32];
	char consumer[32];
};

struct gpiod_chip {
	struct gpiod_line **lines;
	unsigned int num_lines;

	int fd;

	char name[32];
	char label[32];
};

struct gpiod_chip *gpiod_chip_open(const char *path)
{
	struct gpiochip_info info;
	struct gpiod_chip *chip;
	int status, fd;

	fd = open(path, O_RDWR | O_CLOEXEC);
	if (fd < 0)
		return NULL;

	chip = malloc(sizeof(*chip));
	if (!chip)
		goto err_close_fd;

	memset(chip, 0, sizeof(*chip));
	memset(&info, 0, sizeof(info));

	status = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &info);
	if (status < 0)
		goto err_free_chip;

	chip->fd = fd;
	chip->num_lines = info.lines;

	/*
	 * GPIO device must have a name - don't bother checking this field. In
	 * the worst case (would have to be a weird kernel bug) it'll be empty.
	 */
	strncpy(chip->name, info.name, sizeof(chip->name));

	/*
	 * The kernel sets the label of a GPIO device to "unknown" if it
	 * hasn't been defined in DT, board file etc. On the off-chance that
	 * we got an empty string, do the same.
	 */
	if (info.label[0] == '\0')
		strncpy(chip->label, "unknown", sizeof(chip->label));
	else
		strncpy(chip->label, info.label, sizeof(chip->label));

	return chip;

err_free_chip:
	free(chip);
err_close_fd:
	close(fd);

	return NULL;
}

void gpiod_chip_close(struct gpiod_chip *chip)
{
	struct gpiod_line *line;
	unsigned int i;

	if (chip->lines) {
		for (i = 0; i < chip->num_lines; i++) {
			line = chip->lines[i];
			if (line) {
				gpiod_line_release(line);
				free(line);
			}
		}

		free(chip->lines);
	}

	close(chip->fd);
	free(chip);
}

const char *gpiod_chip_name(struct gpiod_chip *chip)
{
	return chip->name;
}

const char *gpiod_chip_label(struct gpiod_chip *chip)
{
	return chip->label;
}

unsigned int gpiod_chip_num_lines(struct gpiod_chip *chip)
{
	return chip->num_lines;
}

struct gpiod_line *
gpiod_chip_get_line(struct gpiod_chip *chip, unsigned int offset)
{
	struct gpiod_line *line;
	int status;

	if (offset >= chip->num_lines) {
		errno = EINVAL;
		return NULL;
	}

	if (!chip->lines) {
		chip->lines = calloc(chip->num_lines,
				     sizeof(struct gpiod_line *));
		if (!chip->lines)
			return NULL;
	}

	if (!chip->lines[offset]) {
		line = malloc(sizeof(*line));
		if (!line)
			return NULL;

		memset(line, 0, sizeof(*line));
		line->fd = -1;

		line->offset = offset;
		line->chip = chip;

		chip->lines[offset] = line;
	} else {
		line = chip->lines[offset];
	}

	status = gpiod_line_update(line);
	if (status < 0)
		return NULL;

	return line;
}

static void line_maybe_update(struct gpiod_line *line)
{
	int status;

	status = gpiod_line_update(line);
	if (status < 0)
		line->up_to_date = false;
}

struct gpiod_chip *gpiod_line_get_chip(struct gpiod_line *line)
{
	return line->chip;
}

unsigned int gpiod_line_offset(struct gpiod_line *line)
{
	return line->offset;
}

const char *gpiod_line_name(struct gpiod_line *line)
{
	return line->name[0] == '\0' ? NULL : line->name;
}

const char *gpiod_line_consumer(struct gpiod_line *line)
{
	return line->consumer[0] == '\0' ? NULL : line->consumer;
}

int gpiod_line_direction(struct gpiod_line *line)
{
	return line->direction;
}

int gpiod_line_active_state(struct gpiod_line *line)
{
	return line->active_state;
}

bool gpiod_line_is_used(struct gpiod_line *line)
{
	return line->used;
}

bool gpiod_line_is_open_drain(struct gpiod_line *line)
{
	return line->open_drain;
}

bool gpiod_line_is_open_source(struct gpiod_line *line)
{
	return line->open_source;
}

bool gpiod_line_needs_update(struct gpiod_line *line)
{
	return !line->up_to_date;
}

int gpiod_line_update(struct gpiod_line *line)
{
	struct gpioline_info info;
	int rv;

	memset(&info, 0, sizeof(info));
	info.line_offset = line->offset;

	rv = ioctl(line->chip->fd, GPIO_GET_LINEINFO_IOCTL, &info);
	if (rv < 0)
		return -1;

	line->direction = info.flags & GPIOLINE_FLAG_IS_OUT
						? GPIOD_LINE_DIRECTION_OUTPUT
						: GPIOD_LINE_DIRECTION_INPUT;
	line->active_state = info.flags & GPIOLINE_FLAG_ACTIVE_LOW
						? GPIOD_LINE_ACTIVE_STATE_LOW
						: GPIOD_LINE_ACTIVE_STATE_HIGH;

	line->used = info.flags & GPIOLINE_FLAG_KERNEL;
	line->open_drain = info.flags & GPIOLINE_FLAG_OPEN_DRAIN;
	line->open_source = info.flags & GPIOLINE_FLAG_OPEN_SOURCE;

	strncpy(line->name, info.name, sizeof(line->name));
	strncpy(line->consumer, info.consumer, sizeof(line->consumer));

	line->up_to_date = true;

	return 0;
}

static bool line_bulk_same_chip(struct gpiod_line_bulk *bulk)
{
	struct gpiod_line *first_line, *line;
	struct gpiod_chip *first_chip, *chip;
	unsigned int i;

	if (bulk->num_lines == 1)
		return true;

	first_line = gpiod_line_bulk_get_line(bulk, 0);
	first_chip = gpiod_line_get_chip(first_line);

	for (i = 1; i < bulk->num_lines; i++) {
		line = bulk->lines[i];
		chip = gpiod_line_get_chip(line);

		if (first_chip != chip) {
			errno = EINVAL;
			return false;
		}
	}

	return true;
}

static bool line_bulk_all_requested(struct gpiod_line_bulk *bulk)
{
	struct gpiod_line *line, **lineptr;

	gpiod_line_bulk_foreach_line(bulk, line, lineptr) {
		if (!gpiod_line_is_requested(line)) {
			errno = EPERM;
			return false;
		}
	}

	return true;
}

static bool line_bulk_all_free(struct gpiod_line_bulk *bulk)
{
	struct gpiod_line *line, **lineptr;

	gpiod_line_bulk_foreach_line(bulk, line, lineptr) {
		if (!gpiod_line_is_free(line)) {
			errno = EBUSY;
			return false;
		}
	}

	return true;
}

static int line_request_values(struct gpiod_line_bulk *bulk,
			       const struct gpiod_line_request_config *config,
			       const int *default_vals)
{
	struct gpiod_line *line, **lineptr;
	struct gpiohandle_request req;
	unsigned int i;
	int rv, fd;

	if ((config->request_type != GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) &&
	    (config->flags & (GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN |
			      GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE))) {
		errno = EINVAL;
		return -1;
	}

	if ((config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN) &&
	    (config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)) {
		errno = EINVAL;
		return -1;
	}

	memset(&req, 0, sizeof(req));

	if (config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN)
		req.flags |= GPIOHANDLE_REQUEST_OPEN_DRAIN;
	if (config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)
		req.flags |= GPIOHANDLE_REQUEST_OPEN_SOURCE;
	if (config->flags & GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW)
		req.flags |= GPIOHANDLE_REQUEST_ACTIVE_LOW;

	if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_INPUT)
		req.flags |= GPIOHANDLE_REQUEST_INPUT;
	else if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
		req.flags |= GPIOHANDLE_REQUEST_OUTPUT;

	req.lines = gpiod_line_bulk_num_lines(bulk);

	gpiod_line_bulk_foreach_line_off(bulk, line, i) {
		req.lineoffsets[i] = gpiod_line_offset(line);
		if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
			req.default_values[i] = !!default_vals[i];
	}

	if (config->consumer)
		strncpy(req.consumer_label, config->consumer,
			sizeof(req.consumer_label) - 1);

	line = gpiod_line_bulk_get_line(bulk, 0);
	fd = line->chip->fd;

	rv = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
	if (rv < 0)
		return -1;

	gpiod_line_bulk_foreach_line(bulk, line, lineptr) {
		line->state = LINE_REQUESTED_VALUES;
		line->fd = req.fd;
		line_maybe_update(line);
	}

	return 0;
}

static int line_request_event_single(struct gpiod_line *line,
			const struct gpiod_line_request_config *config)
{
	struct gpioevent_request req;
	int rv;

	memset(&req, 0, sizeof(req));

	if (config->consumer)
		strncpy(req.consumer_label, config->consumer,
			sizeof(req.consumer_label) - 1);

	req.lineoffset = gpiod_line_offset(line);
	req.handleflags |= GPIOHANDLE_REQUEST_INPUT;

	if (config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN)
		req.handleflags |= GPIOHANDLE_REQUEST_OPEN_DRAIN;
	if (config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)
		req.handleflags |= GPIOHANDLE_REQUEST_OPEN_SOURCE;
	if (config->flags & GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW)
		req.handleflags |= GPIOHANDLE_REQUEST_ACTIVE_LOW;

	if (config->request_type == GPIOD_LINE_REQUEST_EVENT_RISING_EDGE)
		req.eventflags |= GPIOEVENT_REQUEST_RISING_EDGE;
	else if (config->request_type == GPIOD_LINE_REQUEST_EVENT_FALLING_EDGE)
		req.eventflags |= GPIOEVENT_REQUEST_FALLING_EDGE;
	else if (config->request_type == GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES)
		req.eventflags |= GPIOEVENT_REQUEST_BOTH_EDGES;

	rv = ioctl(line->chip->fd, GPIO_GET_LINEEVENT_IOCTL, &req);
	if (rv < 0)
		return -1;

	line->state = LINE_REQUESTED_EVENTS;
	line->fd = req.fd;
	line_maybe_update(line);

	return 0;
}

static int line_request_events(struct gpiod_line_bulk *bulk,
			       const struct gpiod_line_request_config *config)
{
	struct gpiod_line *line;
	unsigned int off;
	int rv, rev;

	gpiod_line_bulk_foreach_line_off(bulk, line, off) {
		rv = line_request_event_single(line, config);
		if (rv) {
			for (rev = off - 1; rev >= 0; rev--) {
				line = gpiod_line_bulk_get_line(bulk, rev);
				gpiod_line_release(line);
			}

			return -1;
		}
	}

	return 0;
}

int gpiod_line_request(struct gpiod_line *line,
		       const struct gpiod_line_request_config *config,
		       int default_val)
{
	struct gpiod_line_bulk bulk;

	gpiod_line_bulk_init(&bulk);
	gpiod_line_bulk_add(&bulk, line);

	return gpiod_line_request_bulk(&bulk, config, &default_val);
}

static bool line_request_is_direction(int request)
{
	return request == GPIOD_LINE_REQUEST_DIRECTION_AS_IS ||
	       request == GPIOD_LINE_REQUEST_DIRECTION_INPUT ||
	       request == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;
}

static bool line_request_is_events(int request)
{
	return request == GPIOD_LINE_REQUEST_EVENT_FALLING_EDGE ||
	       request == GPIOD_LINE_REQUEST_EVENT_RISING_EDGE ||
	       request == GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES;
}

int gpiod_line_request_bulk(struct gpiod_line_bulk *bulk,
			    const struct gpiod_line_request_config *config,
			    const int *default_vals)
{
	if (!line_bulk_same_chip(bulk) || !line_bulk_all_free(bulk))
		return -1;

	if (line_request_is_direction(config->request_type))
		return line_request_values(bulk, config, default_vals);
	else if (line_request_is_events(config->request_type))
		return line_request_events(bulk, config);

	errno = EINVAL;
	return -1;
}

void gpiod_line_release(struct gpiod_line *line)
{
	struct gpiod_line_bulk bulk;

	gpiod_line_bulk_init(&bulk);
	gpiod_line_bulk_add(&bulk, line);

	gpiod_line_release_bulk(&bulk);
}

void gpiod_line_release_bulk(struct gpiod_line_bulk *bulk)
{
	struct gpiod_line *line, **lineptr;

	gpiod_line_bulk_foreach_line(bulk, line, lineptr) {
		if (line->state != LINE_FREE) {
			close(line->fd);
			line->state = LINE_FREE;
		}
	}
}

bool gpiod_line_is_requested(struct gpiod_line *line)
{
	return (line->state == LINE_REQUESTED_VALUES ||
		line->state == LINE_REQUESTED_EVENTS);
}

bool gpiod_line_is_free(struct gpiod_line *line)
{
	return line->state == LINE_FREE;
}

int gpiod_line_get_value(struct gpiod_line *line)
{
	struct gpiod_line_bulk bulk;
	int status, value;

	gpiod_line_bulk_init(&bulk);
	gpiod_line_bulk_add(&bulk, line);

	status = gpiod_line_get_value_bulk(&bulk, &value);
	if (status < 0)
		return -1;

	return value;
}

int gpiod_line_get_value_bulk(struct gpiod_line_bulk *bulk, int *values)
{
	struct gpiohandle_data data;
	struct gpiod_line *first;
	unsigned int i;
	int status, fd;

	if (!line_bulk_same_chip(bulk) || !line_bulk_all_requested(bulk))
		return -1;

	first = gpiod_line_bulk_get_line(bulk, 0);

	memset(&data, 0, sizeof(data));

	fd = first->fd;

	status = ioctl(fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
	if (status < 0)
		return -1;

	for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++)
		values[i] = data.values[i];

	return 0;
}

int gpiod_line_set_value(struct gpiod_line *line, int value)
{
	struct gpiod_line_bulk bulk;

	gpiod_line_bulk_init(&bulk);
	gpiod_line_bulk_add(&bulk, line);

	return gpiod_line_set_value_bulk(&bulk, &value);
}

int gpiod_line_set_value_bulk(struct gpiod_line_bulk *bulk, const int *values)
{
	struct gpiohandle_data data;
	struct gpiod_line *line;
	unsigned int i;
	int status;

	if (!line_bulk_same_chip(bulk) || !line_bulk_all_requested(bulk))
		return -1;

	memset(&data, 0, sizeof(data));

	for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++)
		data.values[i] = (uint8_t)!!values[i];

	line = gpiod_line_bulk_get_line(bulk, 0);
	status = ioctl(line->fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
	if (status < 0)
		return -1;

	return 0;
}

int gpiod_line_event_wait(struct gpiod_line *line,
			  const struct timespec *timeout)
{
	struct gpiod_line_bulk bulk;

	gpiod_line_bulk_init(&bulk);
	gpiod_line_bulk_add(&bulk, line);

	return gpiod_line_event_wait_bulk(&bulk, timeout, NULL);
}

int gpiod_line_event_wait_bulk(struct gpiod_line_bulk *bulk,
			       const struct timespec *timeout,
			       struct gpiod_line_bulk *event_bulk)
{
	struct pollfd fds[GPIOD_LINE_BULK_MAX_LINES];
	unsigned int off, num_lines;
	struct gpiod_line *line;
	int rv;

	if (!line_bulk_same_chip(bulk) || !line_bulk_all_requested(bulk))
		return -1;

	memset(fds, 0, sizeof(fds));
	num_lines = gpiod_line_bulk_num_lines(bulk);

	gpiod_line_bulk_foreach_line_off(bulk, line, off) {
		fds[off].fd = line->fd;
		fds[off].events = POLLIN | POLLPRI;
	}

	rv = ppoll(fds, num_lines, timeout, NULL);
	if (rv < 0)
		return -1;
	else if (rv == 0)
		return 0;

	if (event_bulk) {
		gpiod_line_bulk_init(event_bulk);

		for (off = 0; off < num_lines; off++) {
			if (fds[off].revents) {
				line = gpiod_line_bulk_get_line(bulk, off);
				gpiod_line_bulk_add(event_bulk, line);
				if (!--rv)
					break;
			}
		}
	}

	return 1;
}

int gpiod_line_event_read(struct gpiod_line *line,
			  struct gpiod_line_event *event)
{
	if (line->state != LINE_REQUESTED_EVENTS) {
		errno = EPERM;
		return -1;
	}

	return gpiod_line_event_read_fd(line->fd, event);
}

int gpiod_line_event_get_fd(struct gpiod_line *line)
{
	if (line->state != LINE_REQUESTED_EVENTS) {
		errno = EPERM;
		return -1;
	}

	return line->fd;
}

int gpiod_line_event_read_fd(int fd, struct gpiod_line_event *event)
{
	struct gpioevent_data evdata;
	ssize_t rd;

	memset(&evdata, 0, sizeof(evdata));

	rd = read(fd, &evdata, sizeof(evdata));
	if (rd < 0) {
		return -1;
	} else if (rd != sizeof(evdata)) {
		errno = EIO;
		return -1;
	}

	event->event_type = evdata.id == GPIOEVENT_EVENT_RISING_EDGE
						? GPIOD_LINE_EVENT_RISING_EDGE
						: GPIOD_LINE_EVENT_FALLING_EDGE;

	event->ts.tv_sec = evdata.timestamp / 1000000000ULL;
	event->ts.tv_nsec = evdata.timestamp % 1000000000ULL;

	return 0;
}
