/*
 *   cli_usock.c - Teamd daemon control library teamd Unix Domain socket client
 *   Copyright (C) 2013-2015 Jiri Pirko <jiri@resnulli.us>
 *
 *   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.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <teamdctl.h>
#include "teamdctl_private.h"
#include "../teamd/teamd_usock_common.h"

/* \cond HIDDEN_SYMBOLS */
struct cli_usock_priv {
	int sock;
};
/* \endcond */

static int cli_usock_process_msg(struct teamdctl *tdc, char *msg,
				 char **p_replystr)
{
	char *str;
	char *rest = msg;

	str = teamd_usock_msg_getline(&rest);
	if (!str) {
		err(tdc, "usock: Incomplete message.\n");
		return -EINVAL;;
	}

	if (!strcmp(TEAMD_USOCK_REPLY_SUCC_PREFIX, str)) {
		*p_replystr = rest;
	} else if (!strcmp(TEAMD_USOCK_REPLY_ERR_PREFIX, str)) {
		str = teamd_usock_msg_getline(&rest);
		if (!str) {
			err(tdc, "usock: Incomplete message.\n");
			return -EINVAL;;
		}
		err(tdc, "usock: Error message received: \"%s\"", str);
		str = teamd_usock_msg_getline(&rest);
		if (!str) {
			err(tdc, "usock: Incomplete message.\n");
			return -EINVAL;;
		}
		err(tdc, "usock: Error message content: \"%s\"", str);
		return -EINVAL;;
	} else {
		err(tdc, "usock: Unsupported message type.\n");
		return -EINVAL;
	}
	return 0;
}

static int cli_usock_send(int sock, char *msg)
{
	int err;

	err = send(sock, msg, strlen(msg), MSG_NOSIGNAL);
	if (err == -1)
		return -errno;
	return 0;
}

#define WAIT_SEC (TEAMDCTL_REPLY_TIMEOUT / 1000)
#define WAIT_USEC (TEAMDCTL_REPLY_TIMEOUT % 1000 * 1000)

static int cli_usock_wait_recv(int sock)
{
	fd_set rfds;
	int fdmax;
	int ret;
	struct timeval tv;

	tv.tv_sec = WAIT_SEC;
	tv.tv_usec = WAIT_USEC;
	FD_ZERO(&rfds);
	FD_SET(sock, &rfds);
	fdmax = sock + 1;
	ret = select(fdmax, &rfds, NULL, NULL, &tv);
	if (ret == -1)
		return -errno;
	if (!FD_ISSET(sock, &rfds))
		return -ETIMEDOUT;
	return 0;
}

static int myasprintf(char **p_str, const char *fmt, ...)
{
	char *newstr;
	va_list ap;
	int ret;

	va_start(ap, fmt);
	ret = vasprintf(&newstr, fmt, ap);
	va_end(ap);
	if (ret == -1)
		return -ENOMEM;
	free(*p_str);
	*p_str = newstr;
	return 0;
}

char *__strencode(char *str)
{
	char *newstr;
	int i, j;
	size_t len = strlen(str);

	for (i = 0; i < strlen(str); i++) {
		switch (str[i]) {
		case '\n':
		case '\\':
			len++;
		}
	}
	newstr = malloc(sizeof(char) * (len + 1));
	if (!newstr)
		return NULL;
	j = 0;
	for (i = 0; i <= strlen(str); i++) {
		switch (str[i]) {
		case '\n':
			newstr[j++] = '\\';
			newstr[j++] = 'n';
			break;
		case '\\':
			newstr[j++] = '\\';
			newstr[j++] = '\\';
			break;
		default:
			newstr[j++] = str[i];
		}
	}
	return newstr;
}

static int cli_usock_method_call(struct teamdctl *tdc, const char *method_name,
				 char **p_reply, void *priv,
				 const char *fmt, va_list ap)
{
	struct cli_usock_priv *cli_usock = priv;
	char *str;
	char *msg = NULL;
	char *recv_message = NULL; /* gcc needs this initialized */
	char *replystr;
	int err;

	dbg(tdc, "usock: Calling method \"%s\"", method_name);
	err= myasprintf(&msg, "%s\n%s\n", TEAMD_USOCK_REQUEST_PREFIX,
					  method_name);
	if (err)
		return err;
	while (*fmt) {
		switch (*fmt++) {
		case 's': /* string */
			str = __strencode(va_arg(ap, char *));
			if (!str) {
				err = -ENOMEM;
				goto free_msg;
			}
			err = myasprintf(&msg, "%s%s\n", msg, str);
			free(str);
			if (err)
				goto free_msg;
			break;
		default:
			err(tdc, "usock: Unknown argument type requested.");
			err = -EINVAL;
			goto free_msg;
		}
	}

	err = cli_usock_send(cli_usock->sock, msg);
	if (err)
		goto free_msg;

	err = cli_usock_wait_recv(cli_usock->sock);
	if (err) {
		if (err == -ETIMEDOUT)
			dbg(tdc, "usock: Wait for reply timed-out.");
		goto free_msg;
	}

	err = teamd_usock_recv_msg(cli_usock->sock, &recv_message);
	if (err)
		goto free_msg;

	err = cli_usock_process_msg(tdc, recv_message, &replystr);
	if (err)
		goto free_recv_message;

	if (p_reply) {
		replystr = strdup(replystr);
		if (!replystr) {
			err = -ENOMEM;
			goto free_recv_message;
		}
		*p_reply = replystr;
	}

free_recv_message:
	free(recv_message);
free_msg:
	free(msg);
	return err;
}

static int cli_usock_init(struct teamdctl *tdc, const char *team_name,
			  void *priv)
{
	struct cli_usock_priv *cli_usock = priv;
	struct sockaddr_un addr;
	int err;

	memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	teamd_usock_get_sockpath(addr.sun_path, sizeof(addr.sun_path),
				 team_name);

	cli_usock->sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
	if (cli_usock->sock == -1) {
		err(tdc, "usock: Failed to create socket.");
		return -errno;
	}

	err = connect(cli_usock->sock, (struct sockaddr *) &addr,
		      strlen(addr.sun_path) + sizeof(addr.sun_family));
	if (err == -1) {
		err(tdc, "usock: Failed to connect socket (%s).",
		    addr.sun_path);
		close(cli_usock->sock);
		return -errno;
	}
	return 0;
}

void cli_usock_fini(struct teamdctl *tdc, void *priv)
{
	struct cli_usock_priv *cli_usock = priv;

	close(cli_usock->sock);
}

static const struct teamdctl_cli cli_usock = {
	.name = "usock",
	.init = cli_usock_init,
	.fini = cli_usock_fini,
	.method_call = cli_usock_method_call,
	.priv_size = sizeof(struct cli_usock_priv),
};

const struct teamdctl_cli *teamdctl_cli_usock_get(void)
{
	return &cli_usock;
}
