/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2013  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>

#include <gdbus.h>

#include "input.h"
#include "dbus_helpers.h"
#include "agent.h"

#define AGENT_INTERFACE      "net.connman.Agent"
#define VPN_AGENT_INTERFACE  "net.connman.vpn.Agent"

static DBusConnection *agent_connection;

struct agent_input_data {
	const char *attribute;
	bool requested;
	char *prompt;
	connmanctl_input_func_t func;
};

struct agent_data {
	struct agent_input_data *input;
	char *interface;
	bool registered;
	DBusMessage *message;
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter dict;
	GDBusMethodFunction pending_function;
};

static void request_input_ssid_return(char *input, void *user_data);
static void request_input_passphrase_return(char *input, void *user_data);
static void request_input_string_return(char *input, void *user_data);

enum requestinput {
	SSID                    = 0,
	IDENTITY                = 1,
	PASSPHRASE              = 2,
	WPS                     = 3,
	WISPR_USERNAME          = 4,
	WISPR_PASSPHRASE        = 5,
	REQUEST_INPUT_MAX       = 6,
};

static struct agent_input_data agent_input_handler[] = {
	{ "Name", false, "Hidden SSID name? ", request_input_ssid_return },
	{ "Identity", false, "EAP username? ", request_input_string_return },
	{ "Passphrase", false, "Passphrase? ",
	  request_input_passphrase_return },
	{ "WPS", false, "WPS PIN (empty line for pushbutton)? " ,
	  request_input_string_return },
	{ "Username", false, "WISPr username? ", request_input_string_return },
	{ "Password", false, "WISPr password? ", request_input_string_return },
	{ },
};

static struct agent_data agent_request = {
	agent_input_handler,
	AGENT_INTERFACE,
};

static struct agent_input_data vpnagent_input_handler[] = {
	{ "OpenConnect.Cookie", false, "OpenConnect Cookie? ",
	  request_input_string_return },
	{ "OpenConnect.ServerCert", false,
	  "OpenConnect server certificate hash? ",
	  request_input_string_return },
	{ "OpenConnect.VPNHost", false, "OpenConnect VPN server? ",
	  request_input_string_return },
	{ "Username", false, "VPN username? ", request_input_string_return },
	{ "Password", false, "VPN password? ", request_input_string_return },
	{ },
};

static struct agent_data vpn_agent_request = {
	vpnagent_input_handler,
	VPN_AGENT_INTERFACE,
};

static int confirm_input(char *input)
{
	int i;

	if (!input)
		return -1;

	for (i = 0; input[i] != '\0'; i++)
		if (isspace(input[i]) == 0)
			break;

	if (strcasecmp(&input[i], "yes") == 0 ||
			strcasecmp(&input[i], "y") == 0)
		return 1;

	if (strcasecmp(&input[i], "no") == 0 ||
			strcasecmp(&input[i], "n") == 0)
		return 0;

	return -1;
}

static char *strip_path(char *path)
{
	char *name = strrchr(path, '/');
	if (name)
		name++;
	else
		name = path;

	return name;
}

static char *agent_path(void)
{
	static char *path = NULL;

	if (!path)
		path = g_strdup_printf("/net/connman/connmanctl%d", getpid());

	return path;
}

static void pending_message_remove(struct agent_data *request)
{
	if (request->message) {
		dbus_message_unref(request->message);
		request->message = NULL;
	}

	if (request->reply) {
		dbus_message_unref(request->reply);
		request->reply = NULL;
	}
}

static void pending_command_complete(char *message)
{
	struct agent_data *next_request = NULL;
	DBusMessage *pending_message;
	GDBusMethodFunction pending_function;

	__connmanctl_save_rl();

	fprintf(stdout, "%s", message);

	__connmanctl_redraw_rl();

	if (__connmanctl_is_interactive() == true)
		__connmanctl_command_mode();
	else
		__connmanctl_agent_mode("", NULL, NULL);

	if (agent_request.message)
		next_request = &agent_request;
	else if (vpn_agent_request.message)
		next_request = &vpn_agent_request;

	if (!next_request)
		return;

	pending_message = next_request->message;
	pending_function = next_request->pending_function;
	next_request->pending_function = NULL;

	pending_function(agent_connection, next_request->message,
			next_request);

	dbus_message_unref(pending_message);
}

static bool handle_message(DBusMessage *message, struct agent_data *request,
		GDBusMethodFunction function)
{
	if (!agent_request.pending_function &&
			!vpn_agent_request.pending_function)
		return true;

	request->message = dbus_message_ref(message);
	request->pending_function = function;

	return false;
}

static DBusMessage *agent_release(DBusConnection *connection,
		DBusMessage *message, void *user_data)
{
	struct agent_data *request = user_data;

	if (handle_message(message, request, agent_release) == false)
		return NULL;

	g_dbus_unregister_interface(connection, agent_path(),
			request->interface);
	request->registered = false;

	pending_message_remove(request);

	if (strcmp(request->interface, AGENT_INTERFACE) == 0)
		pending_command_complete("Agent unregistered by ConnMan\n");
	else
		pending_command_complete("VPN Agent unregistered by ConnMan "
				"VPNd\n");

	if (__connmanctl_is_interactive() == false)
		__connmanctl_quit();

	return dbus_message_new_method_return(message);
}

static DBusMessage *agent_cancel(DBusConnection *connection,
		DBusMessage *message, void *user_data)
{
	struct agent_data *request = user_data;

	if (handle_message(message, request, agent_cancel) == false)
		return NULL;

	pending_message_remove(request);

	if (strcmp(request->interface, AGENT_INTERFACE) == 0)
		pending_command_complete("Agent request cancelled by "
				"ConnMan\n");
	else
		pending_command_complete("VPN Agent request cancelled by "
				"ConnMan VPNd\n");

	return dbus_message_new_method_return(message);
}

static void request_browser_return(char *input, void *user_data)
{
	struct agent_data *request = user_data;

	switch (confirm_input(input)) {
	case 1:
		g_dbus_send_reply(agent_connection, request->message,
				DBUS_TYPE_INVALID);
		break;
	case 0:
		g_dbus_send_error(agent_connection, request->message,
				"net.connman.Agent.Error.Canceled", NULL);
		break;
	default:
		return;
	}

	pending_message_remove(request);
	pending_command_complete("");
}

static DBusMessage *agent_request_browser(DBusConnection *connection,
		DBusMessage *message, void *user_data)
{
	struct agent_data *request = user_data;
	DBusMessageIter iter;
	char *service, *url;

	if (handle_message(message, request, agent_request_browser) == false)
		return NULL;

	dbus_message_iter_init(message, &iter);

	dbus_message_iter_get_basic(&iter, &service);
	dbus_message_iter_next(&iter);
	dbus_message_iter_get_basic(&iter, &url);

	__connmanctl_save_rl();
	fprintf(stdout, "Agent RequestBrowser %s\n", strip_path(service));
	fprintf(stdout, "  %s\n", url);
	__connmanctl_redraw_rl();

	request->message = dbus_message_ref(message);
	__connmanctl_agent_mode("Connected (yes/no)? ",
			request_browser_return, request);

	return NULL;
}

static void report_error_return(char *input, void *user_data)
{
	struct agent_data *request = user_data;

	switch (confirm_input(input)) {
	case 1:
		if (strcmp(request->interface, AGENT_INTERFACE) == 0)
			g_dbus_send_error(agent_connection, request->message,
					"net.connman.Agent.Error.Retry", NULL);
		else
			g_dbus_send_error(agent_connection, request->message,
					"net.connman.vpn.Agent.Error.Retry",
					NULL);
		break;
	case 0:
		g_dbus_send_reply(agent_connection, request->message,
				DBUS_TYPE_INVALID);
		break;
	default:
		return;
	}

	pending_message_remove(request);
	pending_command_complete("");
}

static DBusMessage *agent_report_error(DBusConnection *connection,
		DBusMessage *message, void *user_data)
{
	struct agent_data *request = user_data;
	DBusMessageIter iter;
	char *path, *service, *error;

	if (handle_message(message, request, agent_report_error) == false)
		return NULL;

	dbus_message_iter_init(message, &iter);

	dbus_message_iter_get_basic(&iter, &path);
	service = strip_path(path);

	dbus_message_iter_next(&iter);
	dbus_message_iter_get_basic(&iter, &error);

	__connmanctl_save_rl();
	if (strcmp(request->interface, AGENT_INTERFACE) == 0)
		fprintf(stdout, "Agent ReportError %s\n", service);
	else
		fprintf(stdout, "VPN Agent ReportError %s\n", service);
	fprintf(stdout, "  %s\n", error);
	__connmanctl_redraw_rl();

	request->message = dbus_message_ref(message);
	__connmanctl_agent_mode("Retry (yes/no)? ", report_error_return,
			request);

	return NULL;
}

static DBusMessage *agent_report_peer_error(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	struct agent_data *request = user_data;
	char *path, *peer, *error;
	DBusMessageIter iter;

	if (handle_message(message, request,
				agent_report_peer_error) == false)
		return NULL;

	dbus_message_iter_init(message, &iter);

	dbus_message_iter_get_basic(&iter, &path);
	peer = strip_path(path);

	dbus_message_iter_next(&iter);
	dbus_message_iter_get_basic(&iter, &error);

	__connmanctl_save_rl();
	fprintf(stdout, "Agent ReportPeerError %s\n", peer);
	fprintf(stdout, "  %s\n", error);
	__connmanctl_redraw_rl();

	request->message = dbus_message_ref(message);
	__connmanctl_agent_mode("Retry (yes/no)? ",
				report_error_return, request);
	return NULL;
}

static void request_input_next(struct agent_data *request)
{
	int i;

	for (i = 0; request->input[i].attribute; i++) {
		if (request->input[i].requested == true) {
			if (request->input[i].func)
				__connmanctl_agent_mode(request->input[i].prompt,
						request->input[i].func,
						request);
			else
				request->input[i].requested = false;
			return;
		}
	}

	dbus_message_iter_close_container(&request->iter, &request->dict);

	g_dbus_send_message(agent_connection, request->reply);
	request->reply = NULL;

	pending_message_remove(request);
	pending_command_complete("");

	__connmanctl_redraw_rl();
}

static void request_input_append(struct agent_data *request,
		const char *attribute, char *value)
{
	__connmanctl_dbus_append_dict_entry(&request->dict, attribute,
			DBUS_TYPE_STRING, &value);
}

static void request_input_ssid_return(char *input,
		void *user_data)
{
	struct agent_data *request = user_data;
	int len = 0;

	if (input)
		len = strlen(input);

	if (len > 0 && len <= 32) {
		request->input[SSID].requested = false;
		request_input_append(request, request->input[SSID].attribute,
				input);

		request_input_next(request);
	}
}

static void request_input_passphrase_return(char *input, void *user_data)
{
	struct agent_data *request = user_data;
	int len = 0;

	/* TBD passphrase length checking */

	if (input)
		len = strlen(input);

	if (len == 0 && request->input[WPS].requested == false)
		return;

	request->input[PASSPHRASE].requested = false;

	if (len > 0) {
		request_input_append(request,
				request->input[PASSPHRASE].attribute, input);

		request->input[WPS].requested = false;
	}

	request_input_next(request);
}

static void request_input_string_return(char *input, void *user_data)
{
	struct agent_data *request = user_data;
	int i;

	for (i = 0; request->input[i].attribute; i++) {
		if (request->input[i].requested == true) {
			request_input_append(request,
					request->input[i].attribute, input);
			request->input[i].requested = false;
			break;
		}
	}

	request_input_next(request);
}

static void parse_agent_request(struct agent_data *request,
						DBusMessageIter *iter)
{
	DBusMessageIter dict, entry, variant, dict_entry;
	DBusMessageIter field_entry, field_value;
	char *field, *argument, *value;
	char *attr_type = NULL;
	int i;

	dbus_message_iter_recurse(iter, &dict);

	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {

		dbus_message_iter_recurse(&dict, &entry);

		dbus_message_iter_get_basic(&entry, &field);

		dbus_message_iter_next(&entry);

		dbus_message_iter_recurse(&entry, &variant);
		dbus_message_iter_recurse(&variant, &dict_entry);

		while (dbus_message_iter_get_arg_type(&dict_entry)
				== DBUS_TYPE_DICT_ENTRY) {
			dbus_message_iter_recurse(&dict_entry, &field_entry);

			dbus_message_iter_get_basic(&field_entry, &argument);

			dbus_message_iter_next(&field_entry);

			dbus_message_iter_recurse(&field_entry, &field_value);

			if (strcmp(argument, "Type") == 0) {
				dbus_message_iter_get_basic(&field_value,
						&value);
				attr_type = g_strdup(value);
			}

			dbus_message_iter_next(&dict_entry);
		}

		for (i = 0; request->input[i].attribute; i++) {
			if (strcmp(field, request->input[i].attribute) == 0) {
				request->input[i].requested = true;
				break;
			}
		}

		g_free(attr_type);
		attr_type = NULL;

		dbus_message_iter_next(&dict);
	}
}

static DBusMessage *agent_request_input(DBusConnection *connection,
		DBusMessage *message, void *user_data)
{
	struct agent_data *request = user_data;
	DBusMessageIter iter, dict;
	char *service, *str;

	if (handle_message(message, request, agent_request_input) == false)
		return NULL;

	dbus_message_iter_init(message, &iter);

	dbus_message_iter_get_basic(&iter, &str);
	service = strip_path(str);

	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &dict);

	__connmanctl_save_rl();
	if (strcmp(request->interface, AGENT_INTERFACE) == 0)
		fprintf(stdout, "Agent RequestInput %s\n", service);
	else
		fprintf(stdout, "VPN Agent RequestInput %s\n", service);
	__connmanctl_dbus_print(&dict, "  ", " = ", "\n");
	fprintf(stdout, "\n");

	parse_agent_request(request, &iter);

	request->reply = dbus_message_new_method_return(message);
	dbus_message_iter_init_append(request->reply, &request->iter);

	dbus_message_iter_open_container(&request->iter, DBUS_TYPE_ARRAY,
                        DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
                        DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
                        DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
			&request->dict);

	request_input_next(request);

	return NULL;
}

static void request_authorization_return(char *input, void *user_data)
{
	struct agent_data *request = user_data;

	switch (confirm_input(input)) {
	case 1:
		request->reply = dbus_message_new_method_return(
							request->message);
		dbus_message_iter_init_append(request->reply, &request->iter);

		dbus_message_iter_open_container(&request->iter,
				DBUS_TYPE_ARRAY,
				DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
				DBUS_TYPE_STRING_AS_STRING
				DBUS_TYPE_VARIANT_AS_STRING
				DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
				&request->dict);
		dbus_message_iter_close_container(&request->iter,
							&request->dict);
		g_dbus_send_message(agent_connection, request->reply);
		request->reply = NULL;
		break;
	case 0:
		 g_dbus_send_error(agent_connection, request->message,
				 "net.connman.Agent.Error.Rejected", NULL);
		 break;
	default:
		 g_dbus_send_error(agent_connection, request->message,
				 "net.connman.Agent.Error.Canceled", NULL);
		 break;
	}

	pending_message_remove(request);
	pending_command_complete("");
}

static DBusMessage *
agent_request_peer_authorization(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	struct agent_data *request = user_data;
	DBusMessageIter iter, dict;
	char *peer, *str;
	bool input;
	int i;

	if (handle_message(message, request, agent_request_peer_authorization)
								== false)
		return NULL;

	dbus_message_iter_init(message, &iter);

	dbus_message_iter_get_basic(&iter, &str);
	peer = strip_path(str);

	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &dict);

	__connmanctl_save_rl();
	fprintf(stdout, "Agent RequestPeerAuthorization %s\n", peer);
	__connmanctl_dbus_print(&dict, "  ", " = ", "\n");
	fprintf(stdout, "\n");

	parse_agent_request(request, &iter);

	for (input = false, i = 0; request->input[i].attribute; i++) {
		if (request->input[i].requested == true) {
			input = true;
			break;
		}
	}

	if (!input) {
		request->message = dbus_message_ref(message);
		__connmanctl_agent_mode("Accept connection (yes/no)? ",
					request_authorization_return, request);
		return NULL;
	}

	request->reply = dbus_message_new_method_return(message);
	dbus_message_iter_init_append(request->reply, &request->iter);

	dbus_message_iter_open_container(&request->iter, DBUS_TYPE_ARRAY,
                        DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
                        DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
                        DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
			&request->dict);

	request_input_next(request);

	return NULL;
}

static const GDBusMethodTable agent_methods[] = {
	{ GDBUS_ASYNC_METHOD("Release", NULL, NULL, agent_release) },
	{ GDBUS_ASYNC_METHOD("Cancel", NULL, NULL, agent_cancel) },
	{ GDBUS_ASYNC_METHOD("RequestBrowser",
				GDBUS_ARGS({ "service", "o" },
					{ "url", "s" }),
				NULL, agent_request_browser) },
	{ GDBUS_ASYNC_METHOD("ReportError",
				GDBUS_ARGS({ "service", "o" },
					{ "error", "s" }),
				NULL, agent_report_error) },
	{ GDBUS_ASYNC_METHOD("ReportPeerError",
				GDBUS_ARGS({ "peer", "o" },
					{ "error", "s" }),
				NULL, agent_report_peer_error) },
	{ GDBUS_ASYNC_METHOD("RequestInput",
				GDBUS_ARGS({ "service", "o" },
					{ "fields", "a{sv}" }),
				GDBUS_ARGS({ "fields", "a{sv}" }),
				agent_request_input) },
	{ GDBUS_ASYNC_METHOD("RequestPeerAuthorization",
				GDBUS_ARGS({ "peer", "o" },
					{ "fields", "a{sv}" }),
				GDBUS_ARGS({ "fields", "a{sv}" }),
				agent_request_peer_authorization) },
	{ },
};

static int agent_register_return(DBusMessageIter *iter, int errnum,
				 const char *error, void *user_data)
{
	DBusConnection *connection = user_data;

	if (error) {
		g_dbus_unregister_interface(connection, agent_path(),
				AGENT_INTERFACE);
		fprintf(stderr, "Error registering Agent: %s\n", error);
		return 0;
	}

	agent_request.registered = true;
	fprintf(stdout, "Agent registered\n");

	return -EINPROGRESS;
}

static void append_path(DBusMessageIter *iter, void *user_data)
{
	const char *path = user_data;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
}

int __connmanctl_agent_register(DBusConnection *connection)
{
	char *path = agent_path();
	int result;

	if (agent_request.registered == true) {
		fprintf(stderr, "Agent already registered\n");
		return -EALREADY;
	}

	agent_connection = connection;

	if (!g_dbus_register_interface(connection, path,
					AGENT_INTERFACE, agent_methods,
					NULL, NULL, &agent_request, NULL)) {
		fprintf(stderr, "Error: Failed to register Agent callbacks\n");
		return 0;
	}

	result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
			CONNMAN_PATH, "net.connman.Manager", "RegisterAgent",
			agent_register_return, connection, append_path, path);

	if (result != -EINPROGRESS) {
		g_dbus_unregister_interface(connection, agent_path(),
				AGENT_INTERFACE);

		fprintf(stderr, "Error: Failed to register Agent\n");
	}

	return result;
}

static int agent_unregister_return(DBusMessageIter *iter, int errnum,
				   const char *error, void *user_data)
{
	if (error) {
		fprintf(stderr, "Error unregistering Agent: %s\n", error);
		return 0;
	}

	agent_request.registered = false;
	fprintf(stdout, "Agent unregistered\n");

	return 0;
}

int __connmanctl_agent_unregister(DBusConnection *connection)
{
	char *path = agent_path();
	int result;

	if (agent_request.registered == false) {
		fprintf(stderr, "Agent not registered\n");
		return -EALREADY;
	}

	g_dbus_unregister_interface(connection, agent_path(), AGENT_INTERFACE);

	result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
			CONNMAN_PATH, "net.connman.Manager", "UnregisterAgent",
			agent_unregister_return, NULL, append_path, path);

	if (result != -EINPROGRESS)
		fprintf(stderr, "Error: Failed to unregister Agent\n");

	return result;
}

static const GDBusMethodTable vpn_agent_methods[] = {
	{ GDBUS_ASYNC_METHOD("Release", NULL, NULL, agent_release) },
	{ GDBUS_ASYNC_METHOD("Cancel", NULL, NULL, agent_cancel) },
	{ GDBUS_ASYNC_METHOD("ReportError",
				GDBUS_ARGS({ "service", "o" },
					{ "error", "s" }),
				NULL, agent_report_error) },
	{ GDBUS_ASYNC_METHOD("RequestInput",
				GDBUS_ARGS({ "service", "o" },
					{ "fields", "a{sv}" }),
				GDBUS_ARGS({ "fields", "a{sv}" }),
				agent_request_input) },
	{ },
};

static int vpn_agent_register_return(DBusMessageIter *iter, int errnum,
				     const char *error,	void *user_data)
{
	DBusConnection *connection = user_data;

	if (error) {
		g_dbus_unregister_interface(connection, agent_path(),
				VPN_AGENT_INTERFACE);
		fprintf(stderr, "Error registering VPN Agent: %s\n", error);
		return 0;
	}

	vpn_agent_request.registered = true;
	fprintf(stdout, "VPN Agent registered\n");

	return -EINPROGRESS;
}

int __connmanctl_vpn_agent_register(DBusConnection *connection)
{
	char *path = agent_path();
	int result;

	if (vpn_agent_request.registered == true) {
		fprintf(stderr, "VPN Agent already registered\n");
		return -EALREADY;
	}

	agent_connection = connection;

	if (!g_dbus_register_interface(connection, path,
			VPN_AGENT_INTERFACE, vpn_agent_methods,
			NULL, NULL, &vpn_agent_request, NULL)) {
		fprintf(stderr, "Error: Failed to register VPN Agent "
				"callbacks\n");
		return 0;
	}

	result = __connmanctl_dbus_method_call(connection, VPN_SERVICE,
			VPN_PATH, "net.connman.vpn.Manager", "RegisterAgent",
			vpn_agent_register_return, connection, append_path,
			path);

	if (result != -EINPROGRESS) {
		g_dbus_unregister_interface(connection, agent_path(),
				VPN_AGENT_INTERFACE);

		fprintf(stderr, "Error: Failed to register VPN Agent\n");
	}

	return result;
}

static int vpn_agent_unregister_return(DBusMessageIter *iter, int errnum,
		const char *error, void *user_data)
{
	if (error) {
		fprintf(stderr, "Error unregistering VPN Agent: %s\n", error);
		return 0;
	}

	vpn_agent_request.registered = false;
	fprintf(stdout, "VPN Agent unregistered\n");

	return 0;
}

int __connmanctl_vpn_agent_unregister(DBusConnection *connection)
{
	char *path = agent_path();
	int result;

	if (vpn_agent_request.registered == false) {
		fprintf(stderr, "VPN Agent not registered\n");
		return -EALREADY;
	}

	g_dbus_unregister_interface(connection, agent_path(),
			VPN_AGENT_INTERFACE);

	result = __connmanctl_dbus_method_call(connection, VPN_SERVICE,
			VPN_PATH, "net.connman.vpn.Manager", "UnregisterAgent",
			vpn_agent_unregister_return, NULL, append_path, path);

	if (result != -EINPROGRESS)
		fprintf(stderr, "Error: Failed to unregister VPN Agent\n");

	return result;
}
