/*
 * libiio - Library for interfacing industrial I/O (IIO) devices
 *
 * Copyright (C) 2014-2016 Analog Devices, Inc.
 * Author: Paul Cercueil <paul.cercueil@analog.com>
 *
 * This library 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.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 */

#include "debug.h"
#include "iiod-client.h"
#include "iio-lock.h"
#include "iio-private.h"

#include <errno.h>
#include <inttypes.h>
#include <string.h>
#include <stdio.h>

struct iiod_client {
	struct iio_context_pdata *pdata;
	const struct iiod_client_ops *ops;
	struct iio_mutex *lock;
};

static ssize_t iiod_client_read_integer(struct iiod_client *client,
		void *desc, int *val)
{
	unsigned int i;
	char buf[1024], *ptr = NULL, *end;
	ssize_t ret;
	int value;

	do {
		ret = client->ops->read_line(client->pdata,
				desc, buf, sizeof(buf));
		if (ret < 0)
			return ret;

		for (i = 0; i < (unsigned int) ret; i++) {
			if (buf[i] != '\n') {
				if (!ptr)
					ptr = &buf[i];
			} else if (!!ptr) {
				break;
			}
		}
	} while (!ptr);

	buf[i] = '\0';

	value = (int) strtol(ptr, &end, 10);
	if (ptr == end)
		return -EINVAL;

	*val = value;
	return 0;
}

static int iiod_client_exec_command(struct iiod_client *client,
		void *desc, const char *cmd)
{
	int resp;
	ssize_t ret;

	ret = client->ops->write(client->pdata, desc, cmd, strlen(cmd));
	if (ret < 0)
		return (int) ret;

	ret = iiod_client_read_integer(client, desc, &resp);
	return ret < 0 ? (int) ret : resp;
}

static ssize_t iiod_client_write_all(struct iiod_client *client,
		void *desc, const void *src, size_t len)
{
	struct iio_context_pdata *pdata = client->pdata;
	const struct iiod_client_ops *ops = client->ops;
	uintptr_t ptr = (uintptr_t) src;

	while (len) {
		ssize_t ret = ops->write(pdata, desc, (const void *) ptr, len);

		if (ret < 0) {
			if (ret == -EINTR)
				continue;
			else
				return ret;
		}

		if (ret == 0)
			return -EPIPE;

		ptr += ret;
		len -= ret;
	}

	return (ssize_t) (ptr - (uintptr_t) src);
}

static ssize_t iiod_client_read_all(struct iiod_client *client,
		void *desc, void *dst, size_t len)
{
	struct iio_context_pdata *pdata = client->pdata;
	const struct iiod_client_ops *ops = client->ops;
	uintptr_t ptr = (uintptr_t) dst;

	while (len) {
		ssize_t ret = ops->read(pdata, desc, (void *) ptr, len);

		if (ret < 0) {
			if (ret == -EINTR)
				continue;
			else
				return ret;
		}

		if (ret == 0)
			return -EPIPE;

		ptr += ret;
		len -= ret;
	}

	return (ssize_t) (ptr - (uintptr_t) dst);
}

struct iiod_client * iiod_client_new(struct iio_context_pdata *pdata,
		struct iio_mutex *lock, const struct iiod_client_ops *ops)
{
	struct iiod_client *client;

	client = malloc(sizeof(*client));
	if (!client) {
		errno = ENOMEM;
		return NULL;
	}

	client->lock = lock;
	client->pdata = pdata;
	client->ops = ops;
	return client;
}

void iiod_client_destroy(struct iiod_client *client)
{
	free(client);
}

int iiod_client_get_version(struct iiod_client *client, void *desc,
		unsigned int *major, unsigned int *minor, char *git_tag)
{
	struct iio_context_pdata *pdata = client->pdata;
	const struct iiod_client_ops *ops = client->ops;
	char buf[256], *ptr = buf, *end;
	long maj, min;
	int ret;

	iio_mutex_lock(client->lock);

	ret = ops->write(pdata, desc, "VERSION\r\n", sizeof("VERSION\r\n") - 1);
	if (ret < 0) {
		iio_mutex_unlock(client->lock);
		return ret;
	}

	ret = ops->read_line(pdata, desc, buf, sizeof(buf));
	iio_mutex_unlock(client->lock);

	if (ret < 0)
		return ret;

	maj = strtol(ptr, &end, 10);
	if (ptr == end)
		return -EIO;

	ptr = end + 1;
	min = strtol(ptr, &end, 10);
	if (ptr == end)
		return -EIO;

	ptr = end + 1;
	if (buf + ret < ptr + 8)
		return -EIO;

	/* Strip the \n */
	ptr[buf + ret - ptr - 1] = '\0';

	if (major)
		*major = (unsigned int) maj;
	if (minor)
		*minor = (unsigned int) min;
	if (git_tag)
		strncpy(git_tag, ptr, 8);
	return 0;
}

int iiod_client_get_trigger(struct iiod_client *client, void *desc,
		const struct iio_device *dev, const struct iio_device **trigger)
{
	const struct iio_context *ctx = iio_device_get_context(dev);
	unsigned int i, nb_devices = iio_context_get_devices_count(ctx);
	char buf[1024];
	unsigned int name_len;
	int ret;

	iio_snprintf(buf, sizeof(buf), "GETTRIG %s\r\n",
			iio_device_get_id(dev));

	iio_mutex_lock(client->lock);
	ret = iiod_client_exec_command(client, desc, buf);

	if (ret == 0)
		*trigger = NULL;
	if (ret <= 0)
		goto out_unlock;

	if ((unsigned int) ret > sizeof(buf) - 1) {
		ret = -EIO;
		goto out_unlock;
	}

	name_len = ret;

	ret = (int) iiod_client_read_all(client, desc, buf, name_len + 1);
	if (ret < 0)
		goto out_unlock;

	ret = -ENXIO;

	for (i = 0; i < nb_devices; i++) {
		struct iio_device *cur = iio_context_get_device(ctx, i);

		if (iio_device_is_trigger(cur)) {
			const char *name = iio_device_get_name(cur);

			if (!name)
				continue;

			if (!strncmp(name, buf, name_len)) {
				*trigger = cur;
				ret = 0;
				goto out_unlock;
			}
		}
	}

out_unlock:
	iio_mutex_unlock(client->lock);
	return ret;
}

int iiod_client_set_trigger(struct iiod_client *client, void *desc,
		const struct iio_device *dev, const struct iio_device *trigger)
{
	char buf[1024];
	int ret;

	if (trigger) {
		iio_snprintf(buf, sizeof(buf), "SETTRIG %s %s\r\n",
				iio_device_get_id(dev),
				iio_device_get_id(trigger));
	} else {
		iio_snprintf(buf, sizeof(buf), "SETTRIG %s\r\n",
				iio_device_get_id(dev));
	}

	iio_mutex_lock(client->lock);
	ret = iiod_client_exec_command(client, desc, buf);
	iio_mutex_unlock(client->lock);
	return ret;
}

int iiod_client_set_kernel_buffers_count(struct iiod_client *client, void *desc,
		const struct iio_device *dev, unsigned int nb_blocks)
{
	int ret;
	char buf[1024];

	iio_snprintf(buf, sizeof(buf), "SET %s BUFFERS_COUNT %u\r\n",
			iio_device_get_id(dev), nb_blocks);

	iio_mutex_lock(client->lock);
	ret = iiod_client_exec_command(client, desc, buf);
	iio_mutex_unlock(client->lock);
	return ret;
}

int iiod_client_set_timeout(struct iiod_client *client,
		void *desc, unsigned int timeout)
{
	int ret;
	char buf[1024];

	iio_snprintf(buf, sizeof(buf), "TIMEOUT %u\r\n", timeout);

	iio_mutex_lock(client->lock);
	ret = iiod_client_exec_command(client, desc, buf);
	iio_mutex_unlock(client->lock);
	return ret;
}

static int iiod_client_discard(struct iiod_client *client, void *desc,
		char *buf, size_t buf_len, size_t to_discard)
{
	do {
		size_t read_len;
		ssize_t ret;

		if (to_discard > buf_len)
			read_len = buf_len;
		else
			read_len = to_discard;

		ret = iiod_client_read_all(client, desc, buf, read_len);
		if (ret < 0)
			return ret;

		to_discard -= (size_t) ret;
	} while (to_discard);

	return 0;
}

ssize_t iiod_client_read_attr(struct iiod_client *client, void *desc,
		const struct iio_device *dev, const struct iio_channel *chn,
		const char *attr, char *dest, size_t len, enum iio_attr_type type)
{
	const char *id = iio_device_get_id(dev);
	char buf[1024];
	ssize_t ret;

	if (attr) {
		if (chn) {
			if (!iio_channel_find_attr(chn, attr))
				return -ENOENT;
		} else {
			switch (type) {
				case IIO_ATTR_TYPE_DEVICE:
					if (!iio_device_find_attr(dev, attr))
						return -ENOENT;
					break;
				case IIO_ATTR_TYPE_DEBUG:
					if (!iio_device_find_debug_attr(dev, attr))
						return -ENOENT;
					break;
				case IIO_ATTR_TYPE_BUFFER:
					if (!iio_device_find_buffer_attr(dev, attr))
						return -ENOENT;
					break;
				default:
					return -EINVAL;
			}
		}
	}

	if (chn) {
		iio_snprintf(buf, sizeof(buf), "READ %s %s %s %s\r\n", id,
				iio_channel_is_output(chn) ? "OUTPUT" : "INPUT",
				iio_channel_get_id(chn), attr ? attr : "");
	} else {
		switch (type) {
			case IIO_ATTR_TYPE_DEVICE:
				iio_snprintf(buf, sizeof(buf), "READ %s %s\r\n",
						id, attr ? attr : "");
				break;
			case IIO_ATTR_TYPE_DEBUG:
				iio_snprintf(buf, sizeof(buf), "READ %s DEBUG %s\r\n",
						id, attr ? attr : "");
				break;
			case IIO_ATTR_TYPE_BUFFER:
				iio_snprintf(buf, sizeof(buf), "READ %s BUFFER %s\r\n",
						id, attr ? attr : "");
				break;
		}
	}

	iio_mutex_lock(client->lock);

	ret = (ssize_t) iiod_client_exec_command(client, desc, buf);
	if (ret < 0)
		goto out_unlock;

	if ((size_t) ret + 1 > len) {
		iiod_client_discard(client, desc, dest, len, ret + 1);
		ret = -EIO;
		goto out_unlock;
	}

	/* +1: Also read the trailing \n */
	ret = iiod_client_read_all(client, desc, dest, ret + 1);

	if (ret > 0) {
		/* Discard the trailing \n */
		ret--;

		/* Replace it with a \0 just in case */
		dest[ret] = '\0';
	}

out_unlock:
	iio_mutex_unlock(client->lock);
	return ret;
}

ssize_t iiod_client_write_attr(struct iiod_client *client, void *desc,
		const struct iio_device *dev, const struct iio_channel *chn,
		const char *attr, const char *src, size_t len, enum iio_attr_type type)
{
	struct iio_context_pdata *pdata = client->pdata;
	const struct iiod_client_ops *ops = client->ops;
	const char *id = iio_device_get_id(dev);
	char buf[1024];
	ssize_t ret;
	int resp;

	if (attr) {
		if (chn) {
			if (!iio_channel_find_attr(chn, attr))
				return -ENOENT;
		} else {
			switch (type) {
				case IIO_ATTR_TYPE_DEVICE:
					if (!iio_device_find_attr(dev, attr))
						return -ENOENT;
					break;
				case IIO_ATTR_TYPE_DEBUG:
					if (!iio_device_find_debug_attr(dev, attr))
						return -ENOENT;
					break;
				case IIO_ATTR_TYPE_BUFFER:
					if (!iio_device_find_buffer_attr(dev, attr))
						return -ENOENT;
					break;
				default:
					return -EINVAL;
			}
		}
	}

	if (chn) {
		iio_snprintf(buf, sizeof(buf), "WRITE %s %s %s %s %lu\r\n", id,
				iio_channel_is_output(chn) ? "OUTPUT" : "INPUT",
				iio_channel_get_id(chn), attr ? attr : "",
				(unsigned long) len);
	} else {
		switch (type) {
			case IIO_ATTR_TYPE_DEVICE:
				iio_snprintf(buf, sizeof(buf), "WRITE %s %s %lu\r\n",
						id, attr ? attr : "", (unsigned long) len);
				break;
			case IIO_ATTR_TYPE_DEBUG:
				iio_snprintf(buf, sizeof(buf), "WRITE %s DEBUG %s %lu\r\n",
						id, attr ? attr : "", (unsigned long) len);
				break;
			case IIO_ATTR_TYPE_BUFFER:
				iio_snprintf(buf, sizeof(buf), "WRITE %s BUFFER %s %lu\r\n",
						id, attr ? attr : "", (unsigned long) len);
				break;
		}
	}

	iio_mutex_lock(client->lock);
	ret = ops->write(pdata, desc, buf, strlen(buf));
	if (ret < 0)
		goto out_unlock;

	ret = iiod_client_write_all(client, desc, src, len);
	if (ret < 0)
		goto out_unlock;

	ret = iiod_client_read_integer(client, desc, &resp);
	if (ret < 0)
		goto out_unlock;

	ret = (ssize_t) resp;

out_unlock:
	iio_mutex_unlock(client->lock);
	return ret;
}

struct iio_context * iiod_client_create_context(
		struct iiod_client *client, void *desc)
{
	struct iio_context *ctx = NULL;
	size_t xml_len;
	char *xml;
	int ret;

	iio_mutex_lock(client->lock);
	ret = iiod_client_exec_command(client, desc, "PRINT\r\n");
	if (ret < 0)
		goto out_unlock;

	xml_len = (size_t) ret;
	xml = malloc(xml_len + 1);
	if (!xml) {
		ret = -ENOMEM;
		goto out_unlock;
	}

	/* +1: Also read the trailing \n */
	ret = (int) iiod_client_read_all(client, desc, xml, xml_len + 1);
	if (ret < 0)
		goto out_free_xml;

	ctx = iio_create_xml_context_mem(xml, xml_len);
	if (!ctx)
		ret = -errno;

out_free_xml:
	free(xml);
out_unlock:
	iio_mutex_unlock(client->lock);
	if (!ctx)
		errno = -ret;
	return ctx;
}

int iiod_client_open_unlocked(struct iiod_client *client, void *desc,
		const struct iio_device *dev, size_t samples_count, bool cyclic)
{
	char buf[1024], *ptr;
	size_t i;

	iio_snprintf(buf, sizeof(buf), "OPEN %s %lu ",
			iio_device_get_id(dev), (unsigned long) samples_count);
	ptr = buf + strlen(buf);

	for (i = dev->words; i > 0; i--, ptr += 8) {
		iio_snprintf(ptr, (ptr - buf) + i * 8, "%08" PRIx32,
				dev->mask[i - 1]);
	}

	strcpy(ptr, cyclic ? " CYCLIC\r\n" : "\r\n");

	return iiod_client_exec_command(client, desc, buf);
}

int iiod_client_close_unlocked(struct iiod_client *client, void *desc,
		const struct iio_device *dev)
{
	char buf[1024];

	iio_snprintf(buf, sizeof(buf), "CLOSE %s\r\n", iio_device_get_id(dev));
	return iiod_client_exec_command(client, desc, buf);
}

static int iiod_client_read_mask(struct iiod_client *client,
		void *desc, uint32_t *mask, size_t words)
{
	size_t i;
	ssize_t ret;
	char *buf, *ptr;

	buf = malloc(words * 8 + 1);
	if (!buf)
		return -ENOMEM;

	ret = iiod_client_read_all(client, desc, buf, words * 8 + 1);
	if (ret < 0)
		goto out_buf_free;
	else
		ret = 0;

	buf[words*8] = '\0';

	DEBUG("Reading mask\n");

	for (i = words, ptr = buf; i > 0; i--) {
		sscanf(ptr, "%08" PRIx32, &mask[i - 1]);
		DEBUG("mask[%lu] = 0x%08" PRIx32 "\n",
				(unsigned long)(i - 1), mask[i - 1]);

		ptr = (char *) ((uintptr_t) ptr + 8);
	}

out_buf_free:
	free(buf);
	return (int) ret;
}

ssize_t iiod_client_read_unlocked(struct iiod_client *client, void *desc,
		const struct iio_device *dev, void *dst, size_t len,
		uint32_t *mask, size_t words)
{
	unsigned int nb_channels = iio_device_get_channels_count(dev);
	uintptr_t ptr = (uintptr_t) dst;
	char buf[1024];
	ssize_t ret, read = 0;

	if (!len || words != (nb_channels + 31) / 32)
		return -EINVAL;

	iio_snprintf(buf, sizeof(buf), "READBUF %s %lu\r\n",
			iio_device_get_id(dev), (unsigned long) len);

	ret = iiod_client_write_all(client, desc, buf, strlen(buf));
	if (ret < 0)
		return ret;

	do {
		int to_read;

		ret = iiod_client_read_integer(client, desc, &to_read);
		if (ret < 0)
			return ret;
		if (to_read < 0)
			return (ssize_t) to_read;
		if (!to_read)
			break;

		if (mask) {
			ret = iiod_client_read_mask(client, desc, mask, words);
			if (ret < 0)
				return ret;

			mask = NULL; /* We read the mask only once */
		}

		ret = iiod_client_read_all(client, desc, (char *) ptr, to_read);
		if (ret < 0)
			return ret;

		ptr += ret;
		read += ret;
		len -= ret;
	} while (len);

	return read;
}

ssize_t iiod_client_write_unlocked(struct iiod_client *client, void *desc,
		const struct iio_device *dev, const void *src, size_t len)
{
	ssize_t ret;
	char buf[1024];
	int val;

	iio_snprintf(buf, sizeof(buf), "WRITEBUF %s %lu\r\n",
			dev->id, (unsigned long) len);

	ret = iiod_client_write_all(client, desc, buf, strlen(buf));
	if (ret < 0)
		return ret;

	ret = iiod_client_read_integer(client, desc, &val);
	if (ret < 0)
		return ret;
	if (val < 0)
		return (ssize_t) val;

	ret = iiod_client_write_all(client, desc, src, len);
	if (ret < 0)
		return ret;

	ret = iiod_client_read_integer(client, desc, &val);
	if (ret < 0)
		return ret;
	if (val < 0)
		return (ssize_t) val;

	return (ssize_t) len;
}
