/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2012  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 <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>

#include <glib.h>
#include <gdbus.h>

#include "monitor.h"
#include "services.h"
#include "technology.h"
#include "data_manager.h"

static const char *get_service_name(DBusMessage *message, char *dbus_path)
{
	DBusMessageIter iter, array;

	dbus_message_iter_init(message, &iter);
	dbus_message_iter_recurse(&iter, &array);

	while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
		DBusMessageIter entry, dict;
		struct service_data service;
		char *path;

		dbus_message_iter_recurse(&array, &entry);
		dbus_message_iter_get_basic(&entry, &path);

		if (g_strcmp0(path, dbus_path) == 0) {
			dbus_message_iter_next(&entry);
			dbus_message_iter_recurse(&entry, &dict);
			extract_service_name(&dict, &service);
			return service.name;
		} else {
			dbus_message_iter_next(&array);
		}
	}
	return NULL;
}

static void extract_tech_signal(DBusMessage *message)
{
	DBusMessageIter iter, dict;
	char *path;

	dbus_message_iter_init(message, &iter);

	if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_OBJECT_PATH) {
		dbus_message_iter_get_basic(&iter, &path);
		printf(" { %s }\n", path);
	}
	dbus_message_iter_next(&iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID) {
		dbus_message_iter_recurse(&iter, &dict);
		extract_properties(&dict);
	}
}

static void extract_signal_args(DBusMessage *message)
{
	DBusMessageIter iter, array, dict;
	char *string, *value;
	uint16_t key_int;
	dbus_bool_t bvalue;

	value = NULL;
	key_int = 0;

	dbus_message_iter_init(message, &iter);

	while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID) {
		if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
			dbus_message_iter_get_basic(&iter, &string);
			printf("\n[%s] = ",
			string);
		}
		dbus_message_iter_next(&iter);
		if (dbus_message_iter_get_arg_type(&iter) !=
							DBUS_TYPE_INVALID) {
			dbus_message_iter_recurse(&iter, &array);
			if (dbus_message_iter_get_arg_type(&array) ==
							DBUS_TYPE_STRING) {
				dbus_message_iter_get_basic(&array, &value);
				printf("%s\n", value);
				continue;
			} else if (dbus_message_iter_get_arg_type(&array) ==
							DBUS_TYPE_BOOLEAN) {
				dbus_message_iter_get_basic(&array, &bvalue);
				printf("%s\n", bvalue == TRUE ?
							"True" : "False");
				continue;
			} else if (dbus_message_iter_get_arg_type(&array) ==
							DBUS_TYPE_ARRAY)
				dbus_message_iter_recurse(&array, &dict);
			if (dbus_message_iter_get_arg_type(&dict) ==
						DBUS_TYPE_DICT_ENTRY) {
				iterate_dict(&dict, value, key_int);
				printf("\n");
			} else {
				iterate_array(&array);
				printf("\n");
			}
			dbus_message_iter_next(&iter);
		}
	}
}

int monitor_connman(DBusConnection *connection, char *interface,
				char *signal_name)
{
	char *rule = g_strdup_printf("type='signal',interface='net.connman.%s',"
					"member='%s'", interface, signal_name);
	DBusError err;

	dbus_error_init(&err);
	g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, &err);
	if (dbus_error_is_set(&err)) {
		fprintf(stderr, "Bus setup error:%s\n", err.message);
		return -1;
	}
	dbus_bus_add_match(connection, rule, &err);

	if (dbus_error_is_set(&err)) {
		fprintf(stderr, "Match Error: %s\n", err.message);
		return -1;
	}
	return 0;
}

DBusHandlerResult service_property_changed(DBusConnection *connection,
						DBusMessage *message,
						void *user_data)
{
	DBusMessage *service_message;
	struct service_data service;

	if (dbus_message_is_signal(message, "net.connman.Service",
					    "PropertyChanged")) {
		service_message = get_message(connection, "GetServices");
		if (service_message == NULL)
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

		service.name = get_service_name(service_message,
				(char *) dbus_message_get_path(message));
		printf("\n");
		g_message("Path = %s, Interface = %s\nService = %s",
				dbus_message_get_path(message),
				dbus_message_get_interface(message),
				service.name);
		extract_signal_args(message);

		dbus_message_unref(service_message);
	}

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

DBusHandlerResult tech_property_changed(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	if (dbus_message_is_signal(message, "net.connman.Technology",
					    "PropertyChanged")) {
		printf("\n");
		g_message("Path = %s, Interface = %s",
				dbus_message_get_path(message),
				dbus_message_get_interface(message));
		extract_signal_args(message);
	}
	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

DBusHandlerResult tech_added_removed(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	if (dbus_message_is_signal(message, "net.connman.Manager",
					    "TechnologyAdded")) {
		printf("\n");
		g_message("Path = %s, Interface = %s",
				dbus_message_get_path(message),
				dbus_message_get_interface(message));
		printf("New technology added:\n");
		extract_tech_signal(message);
	} else if (dbus_message_is_signal(message, "net.connman.Manager",
						   "TechnologyRemoved")) {
		printf("\n");
		g_message("Path = %s, Interface = %s",
				dbus_message_get_path(message),
				dbus_message_get_interface(message));
		printf("Technology was removed:\n");
		extract_tech_signal(message);
	}

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

DBusHandlerResult manager_services_changed(DBusConnection *connection,
				DBusMessage *message, void *user_data)
{
	if (dbus_message_is_signal(message, "net.connman.Manager",
						"ServicesChanged")) {
		printf("\n");
		g_message("Path = %s, Interface = %s",
				dbus_message_get_path(message),
				dbus_message_get_interface(message));
		printf("Services Changed, displaying updated "
							"list of services:\n");
		list_properties(connection, "GetServices", NULL);
	}

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

DBusHandlerResult manager_property_changed(DBusConnection *connection,
				DBusMessage *message, void *user_data)
{
	if (dbus_message_is_signal(message, "net.connman.Manager",
					    "PropertyChanged")) {
		printf("\n");
		g_message("Path = %s, Interface = %s",
				dbus_message_get_path(message),
				dbus_message_get_interface(message));
		extract_signal_args(message);
	}

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
