/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2003 Junichiro Kita
 *
 *  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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "kazehakase.h"
#include "kz-proxy-item.h"
#include <glib/gi18n.h>

enum {
	PROP_0,
	PROP_NAME,
	PROP_USE_SAME_PROXY,
	PROP_HTTP_HOST,
	PROP_HTTP_PORT,
	PROP_HTTPS_HOST,
	PROP_HTTPS_PORT,
	PROP_FTP_HOST,
	PROP_FTP_PORT,
	PROP_NO_PROXIES_ON,
};

static void dispose	 (GObject *object);
static void set_property (GObject *object,
                          guint prop_id,
                          const GValue *value,
                          GParamSpec *pspec);
static void get_property (GObject *object,
                          guint prop_id,
                          GValue *value,
                          GParamSpec *pspec);

static gchar *no_proxies_on_default = "127.0.0.1, localhost";
static guint  proxy_port_default = 0;

G_DEFINE_TYPE(KzProxyItem, kz_proxy_item, G_TYPE_OBJECT)

static void
kz_proxy_item_class_init (KzProxyItemClass *klass)
{
        GObjectClass *gobject_class;

        gobject_class = (GObjectClass *) klass;
        gobject_class->dispose = dispose;

	gobject_class->set_property = set_property;
	gobject_class->get_property = get_property;

	g_object_class_install_property(
		gobject_class,
		PROP_NAME,
		g_param_spec_string(
			"name",
			_("Name"),
			_("Tne name of proxy item"),
			NULL,
			G_PARAM_READWRITE));

	g_object_class_install_property(
		gobject_class,
		PROP_USE_SAME_PROXY,
		g_param_spec_boolean(
			"use_same_proxy",
			_("Use http proxy for all"),
			_("Whether to use http proxy for all other protocols"),
			FALSE,
			G_PARAM_READWRITE));

	g_object_class_install_property(
		gobject_class,
		PROP_HTTP_HOST,
		g_param_spec_string(
			"http_host",
			_("Http host"),
			_("Host name of http proxy"),
			NULL,
			G_PARAM_READWRITE));

	g_object_class_install_property(
		gobject_class,
		PROP_HTTP_PORT,
		g_param_spec_uint(
			"http_port",
			_("Http port"),
			_("Port number of http proxy"),
			0, G_MAXUINT,
			8080,
			G_PARAM_READWRITE));

	g_object_class_install_property(
		gobject_class,
		PROP_HTTPS_HOST,
		g_param_spec_string(
			"https_host",
			_("Https host"),
			_("Host name of https proxy"),
			NULL,
			G_PARAM_READWRITE));

	g_object_class_install_property(
		gobject_class,
		PROP_HTTPS_PORT,
		g_param_spec_uint(
			"https_port",
			_("Https port"),
			_("Port number of https proxy"),
			0, G_MAXUINT,
			8080,
			G_PARAM_READWRITE));

	g_object_class_install_property(
		gobject_class,
		PROP_FTP_HOST,
		g_param_spec_string(
			"ftp_host",
			_("Ftp host"),
			_("Host name of ftp proxy"),
			NULL,
			G_PARAM_READWRITE));

	g_object_class_install_property(
		gobject_class,
		PROP_FTP_PORT,
		g_param_spec_uint(
			"ftp_port",
			_("ftp port"),
			_("Port number of ftp proxy"),
			0, G_MAXUINT,
			8080,
			G_PARAM_READWRITE));

	g_object_class_install_property(
		gobject_class,
		PROP_NO_PROXIES_ON,
		g_param_spec_string(
			"no_proxies_on",
			_("No proxies on"),
			_("Host names which we don't use proxies on"),
			NULL,
			G_PARAM_READWRITE));
}

static void
kz_proxy_item_init (KzProxyItem *proxy_item)
{
	proxy_item->name		= NULL;
	proxy_item->use_same_proxy	= FALSE;
	proxy_item->http_host		= NULL;
	proxy_item->http_port		= proxy_port_default;
	proxy_item->https_host		= NULL;
	proxy_item->https_port		= proxy_port_default;
	proxy_item->ftp_host		= NULL;
	proxy_item->ftp_port		= proxy_port_default;
	proxy_item->no_proxies_on	= no_proxies_on_default;
}

static void
dispose (GObject *object)
{
	KzProxyItem *item = KZ_PROXY_ITEM(object);

	g_free(item->name);
	g_free(item->http_host);
	g_free(item->https_host);
	g_free(item->ftp_host);
	if (item->no_proxies_on != no_proxies_on_default)
		g_free(item->no_proxies_on);

	if (G_OBJECT_CLASS (kz_proxy_item_parent_class)->dispose)
		G_OBJECT_CLASS (kz_proxy_item_parent_class)->dispose(object);

}

KzProxyItem *
kz_proxy_item_new (void)
{
	KzProxyItem *item = g_object_new(KZ_TYPE_PROXY_ITEM, NULL);

	return item;
}

static void
set_property (GObject *object,
              guint prop_id,
              const GValue *value,
              GParamSpec *pspec)
{
	KzProxyItem *item = KZ_PROXY_ITEM(object);

	switch (prop_id)
	{
	case PROP_NAME:
		item->name = g_value_dup_string(value);
		break;
	case PROP_USE_SAME_PROXY:
		item->use_same_proxy = g_value_get_boolean(value);
		break;
	case PROP_HTTP_HOST:
		item->http_host = g_value_dup_string(value);
		break;
	case PROP_HTTP_PORT:
		item->http_port = g_value_get_uint(value);
		break;
	case PROP_HTTPS_HOST:
		item->https_host = g_value_dup_string(value);
		break;
	case PROP_HTTPS_PORT:
		item->https_port = g_value_get_uint(value);
		break;
	case PROP_FTP_HOST:
		item->ftp_host = g_value_dup_string(value);
		break;
	case PROP_FTP_PORT:
		item->ftp_port = g_value_get_uint(value);
		break;
	case PROP_NO_PROXIES_ON:
		item->no_proxies_on = g_value_dup_string(value);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
		break;
	}
}

static void
get_property (GObject *object,
              guint prop_id,
              GValue *value,
              GParamSpec *pspec)
{
	KzProxyItem *item = KZ_PROXY_ITEM(object);

	switch (prop_id)
	{
	case PROP_NAME:
		g_value_set_string(value, item->name);
		break;
	case PROP_USE_SAME_PROXY:
		g_value_set_boolean(value, item->use_same_proxy);
		break;
	case PROP_HTTP_HOST:
		g_value_set_string(value, item->http_host);
		break;
	case PROP_HTTP_PORT:
		g_value_set_uint(value, item->http_port);
		break;
	case PROP_HTTPS_HOST:
		g_value_set_string(value, item->https_host);
		break;
	case PROP_HTTPS_PORT:
		g_value_set_uint(value, item->https_port);
		break;
	case PROP_FTP_HOST:
		g_value_set_string(value, item->ftp_host);
		break;
	case PROP_FTP_PORT:
		g_value_set_uint(value, item->ftp_port);
		break;
	case PROP_NO_PROXIES_ON:
		g_value_set_string(value, item->no_proxies_on);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
		break;
	}
}

#define KZ_CONF_PROXY_GET(s, k, v, t)                   \
	kz_profile_get_value(KZ_GET_PROXY,              \
			     s, k, &(v), sizeof(v),     \
			     KZ_PROFILE_VALUE_TYPE_##t)

KzProxyItem *
kz_proxy_find(const char *proxy_name)
{
	KzProxyItem *item;
	gboolean use_same_proxy;
	guint http_port, https_port, ftp_port;
	gchar http_host[1024], https_host[1024], ftp_host[1024];
	gchar no_proxies_on[1024];

	g_return_val_if_fail(proxy_name != NULL, NULL);
	
	item = g_object_new(KZ_TYPE_PROXY_ITEM,
			    "name", proxy_name,
			     NULL);
	
	KZ_CONF_PROXY_GET(proxy_name, "use_same_proxy", use_same_proxy, BOOL);
	KZ_CONF_PROXY_GET(proxy_name, "http_host", http_host, STRING);
	KZ_CONF_PROXY_GET(proxy_name, "http_port", http_port, INT);
	KZ_CONF_PROXY_GET(proxy_name, "no_proxies_on", no_proxies_on, STRING);
	g_object_set(G_OBJECT(item),
		     "use_same_proxy", use_same_proxy,
		     "http_host", http_host,
		     "http_port", http_port,
		     "no_proxies_on", no_proxies_on,
		     NULL);
	if (use_same_proxy)
	{
		g_object_set(G_OBJECT(item),
			     "https_host", http_host,
			     "https_port", http_port,
			     "ftp_host", http_host,
			     "ftp_port", http_port,
			     NULL);
		return item;
	}

	if (KZ_CONF_PROXY_GET(proxy_name, "https_host", https_host, STRING))
	{
		KZ_CONF_PROXY_GET(proxy_name, "https_port", https_port, INT);
		g_object_set(G_OBJECT(item),
			     "https_host", https_host,
			     "https_port", https_port,
			     NULL);
	}

	if (KZ_CONF_PROXY_GET(proxy_name, "ftp_host", ftp_host, STRING))
	{
		KZ_CONF_PROXY_GET(proxy_name, "ftp_port", ftp_port, INT);
		g_object_set(G_OBJECT(item),
			     "ftp_host", ftp_host,
			     "ftp_port", ftp_port,
			     NULL);
	}
	return item;
}

GList *
kz_proxy_get_list (void)
{
	GList *list, *node, *r;

	list = kz_profile_enum_section(KZ_GET_PROXY);
	r = NULL;
	for (node = list; node; node = g_list_next(node))
		r = g_list_append(r, kz_proxy_find(node->data));
	g_list_free(list);
	return r;
}

void
kz_proxy_set_list (GList *proxy_list)
{
}
