/* GLib testing framework examples and tests
 *
 * Copyright (C) 2010 Collabora, Ltd.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <gio/gio.h>
#include <glib.h>

#include "glibintl.h"

#ifdef G_OS_UNIX
#include "gio/gunixsocketaddress.h"
#endif

static const gchar *info = NULL;
static GCancellable *cancellable = NULL;
static gint return_value = 0;

static G_NORETURN void
usage (void)
{
  fprintf (stderr, "Usage: proxy [-s] (uri|host:port|ip:port|path|srv/protocol/domain)\n");
  fprintf (stderr, "       Use -t to enable threading.\n");
  fprintf (stderr, "       Use -s to do synchronous lookups.\n");
  fprintf (stderr, "       Use -c to cancel operation.\n");
  fprintf (stderr, "       Use -e to use enumerator.\n");
  fprintf (stderr, "       Use -inet to use GInetSocketAddress enumerator (ip:port).\n");
#ifdef G_OS_UNIX
  fprintf (stderr, "       Use -unix to use GUnixSocketAddress enumerator (path).\n");
#endif
  fprintf (stderr, "       Use -proxyaddr tp use GProxyAddress enumerator "
                   "(ip:port:protocol:dest_host:dest_port[:username[:password]]).\n");
  fprintf (stderr, "       Use -netaddr to use GNetworkAddress enumerator (host:port).\n");
  fprintf (stderr, "       Use -neturi to use GNetworkAddress enumerator (uri).\n");
  fprintf (stderr, "       Use -netsrv to use GNetworkService enumerator (srv/protocol/domain).\n");
  fprintf (stderr, "       Use -connect to create a connection using GSocketClient object (uri).\n");
  exit (1);
}

static void
print_and_free_error (GError *error)
{
  fprintf (stderr, "Failed to obtain proxies: %s\n", error->message);
  g_error_free (error);
  return_value = 1;
}

static void
print_proxies (const gchar *info, gchar **proxies)
{
  printf ("Proxies for URI '%s' are:\n", info);

  if (proxies == NULL || proxies[0] == NULL)
    printf ("\tnone\n");
  else
    for (; proxies[0]; proxies++)
      printf ("\t%s\n", proxies[0]);
}

static void
_proxy_lookup_cb (GObject *source_object,
		  GAsyncResult *result,
		  gpointer user_data)
{
  GError *error = NULL;
  gchar **proxies;
  GMainLoop *loop = user_data;

  proxies = g_proxy_resolver_lookup_finish (G_PROXY_RESOLVER (source_object),
					    result,
					    &error);
  if (error)
    {
      print_and_free_error (error);
    }
  else
    {
      print_proxies (info, proxies);
      g_strfreev (proxies);
    }

  g_main_loop_quit (loop);
}

static void
use_resolver (gboolean synchronous)
{
  GProxyResolver *resolver;

  resolver = g_proxy_resolver_get_default ();

  if (synchronous)
    {
      GError *error = NULL;
      gchar **proxies;

      proxies = g_proxy_resolver_lookup (resolver, info, cancellable, &error);

      if (error)
	  print_and_free_error (error);
      else
	  print_proxies (info, proxies);

      g_strfreev (proxies);
    }
  else
    {
      GMainLoop *loop = g_main_loop_new (NULL, FALSE);

      g_proxy_resolver_lookup_async (resolver,
				     info,
				     cancellable,
				     _proxy_lookup_cb,
				     loop);

      g_main_loop_run (loop);
      g_main_loop_unref (loop);
    }
}

static void
print_proxy_address (GSocketAddress *sockaddr)
{
  GProxyAddress *proxy = NULL;

  if (sockaddr == NULL)
    {
      printf ("\tdirect://\n");
      return;
    }

  if (G_IS_PROXY_ADDRESS (sockaddr))
    {
      proxy = G_PROXY_ADDRESS (sockaddr);
      printf ("\t%s://", g_proxy_address_get_protocol(proxy));
    }
  else
    {
      printf ("\tdirect://");
    }

  if (G_IS_INET_SOCKET_ADDRESS (sockaddr))
    {
      GInetAddress *inetaddr;
      guint port;
      gchar *addr;

      g_object_get (sockaddr,
		    "address", &inetaddr,
		    "port", &port,
		    NULL);

      addr = g_inet_address_to_string (inetaddr);

      printf ("%s:%u", addr, port);

      g_free (addr);
    }

  if (proxy)
    {
      if (g_proxy_address_get_username(proxy))
        printf (" (Username: %s  Password: %s)",
                g_proxy_address_get_username(proxy),
                g_proxy_address_get_password(proxy));
      printf (" (Hostname: %s, Port: %i)",
              g_proxy_address_get_destination_hostname (proxy),
              g_proxy_address_get_destination_port (proxy));
    }

  printf ("\n");
}

static void
_proxy_enumerate_cb (GObject *object,
		     GAsyncResult *result,
		     gpointer user_data)
{
  GError *error = NULL;
  GMainLoop *loop = user_data;
  GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR (object);
  GSocketAddress *sockaddr;

  sockaddr = g_socket_address_enumerator_next_finish (enumerator,
						      result,
						      &error);
  if (sockaddr)
    {
      print_proxy_address (sockaddr);
      g_socket_address_enumerator_next_async (enumerator,
                                              cancellable,
					      _proxy_enumerate_cb,
					      loop);
      g_object_unref (sockaddr);
    }
  else
    {
      if (error)
	print_and_free_error (error);

      g_main_loop_quit (loop);
    }
}

static void
run_with_enumerator (gboolean synchronous, GSocketAddressEnumerator *enumerator)
{
  GError *error = NULL;

  if (synchronous)
    {
      GSocketAddress *sockaddr;

      while ((sockaddr = g_socket_address_enumerator_next (enumerator,
							   cancellable,
							   &error)))
	{
	  print_proxy_address (sockaddr);
	  g_object_unref (sockaddr);
	}

      if (error)
	print_and_free_error (error);
    }
  else
    {
      GMainLoop *loop = g_main_loop_new (NULL, FALSE);

      g_socket_address_enumerator_next_async (enumerator,
                                              cancellable,
					      _proxy_enumerate_cb,
					      loop);
      g_main_loop_run (loop);
      g_main_loop_unref (loop);
    }
}

static void
use_enumerator (gboolean synchronous)
{
  GSocketAddressEnumerator *enumerator;

  enumerator = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
			     "uri", info,
			     NULL);

  printf ("Proxies for URI '%s' are:\n", info);
  run_with_enumerator (synchronous, enumerator);

  g_object_unref (enumerator);
}

static void
use_inet_address (gboolean synchronous)
{
  GSocketAddressEnumerator *enumerator;
  GSocketAddress *sockaddr;
  GInetAddress *addr = NULL;
  guint port = 0;
  gchar **ip_and_port;

  ip_and_port = g_strsplit (info, ":", 2);

  if (ip_and_port[0])
    {
      addr = g_inet_address_new_from_string (ip_and_port[0]);
      if (ip_and_port [1])
	port = strtoul (ip_and_port [1], NULL, 10);
    }

  g_strfreev (ip_and_port);

  if (addr == NULL || port <= 0 || port >= 65535)
    {
      fprintf (stderr, "Bad 'ip:port' parameter '%s'\n", info);
      if (addr)
	g_object_unref (addr);
      return_value = 1;
      return;
    }

  sockaddr = g_inet_socket_address_new (addr, port);
  g_object_unref (addr);

  enumerator =
    g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
  g_object_unref (sockaddr);

  printf ("Proxies for ip and port '%s' are:\n", info);
  run_with_enumerator (synchronous, enumerator);

  g_object_unref (enumerator);
}

#ifdef G_OS_UNIX
static void
use_unix_address (gboolean synchronous)
{
  GSocketAddressEnumerator *enumerator;
  GSocketAddress *sockaddr;

  sockaddr = g_unix_socket_address_new_with_type (info, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT);

  if (sockaddr == NULL)
    {
      fprintf (stderr, "Failed to create unix socket with name '%s'\n", info);
      return_value = 1;
      return;
    }

  enumerator =
    g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
  g_object_unref (sockaddr);

  printf ("Proxies for path '%s' are:\n", info);
  run_with_enumerator (synchronous, enumerator);

  g_object_unref (enumerator);
}
#endif

static void
use_proxy_address (gboolean synchronous)
{
  GSocketAddressEnumerator *enumerator;
  GSocketAddress *sockaddr;
  GInetAddress *addr;
  guint port = 0;
  gchar *protocol;
  gchar *dest_host;
  guint dest_port;
  gchar *username = NULL;
  gchar *password = NULL;
  gchar **split_info;

  split_info = g_strsplit (info, ":", 7);

  if (!split_info[0]
      || !split_info[1]
      || !split_info[2]
      || !split_info[3]
      || !split_info[4])
    {
      fprintf (stderr, "Bad 'ip:port:protocol:dest_host:dest_port' parameter '%s'\n", info);
      return_value = 1;
      return;
    }

  addr = g_inet_address_new_from_string (split_info[0]);
  port = strtoul (split_info [1], NULL, 10);
  protocol = g_strdup (split_info[2]);
  dest_host = g_strdup (split_info[3]);
  dest_port = strtoul (split_info[4], NULL, 10);
 
  if (split_info[5])
    {
      username = g_strdup (split_info[5]);
      if (split_info[6])
        password = g_strdup (split_info[6]);
    }

  g_strfreev (split_info);

  sockaddr = g_proxy_address_new (addr, port,
                                  protocol, dest_host, dest_port,
                                  username, password);
  
  g_object_unref (addr);
  g_free (protocol);
  g_free (dest_host);
  g_free (username);
  g_free (password);

  enumerator =
    g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
  g_object_unref (sockaddr);

  printf ("Proxies for ip and port '%s' are:\n", info);
  run_with_enumerator (synchronous, enumerator);

  g_object_unref (enumerator);
}

static void
use_network_address (gboolean synchronous)
{
  GError *error = NULL;
  GSocketAddressEnumerator *enumerator;
  GSocketConnectable *connectable;

  connectable = g_network_address_parse (info, -1, &error);

  if (error)
    {
      print_and_free_error (error);
      return;
    }

  enumerator = g_socket_connectable_proxy_enumerate (connectable);
  g_object_unref (connectable);

  printf ("Proxies for hostname and port '%s' are:\n", info);
  run_with_enumerator (synchronous, enumerator);

  g_object_unref (enumerator);
}

static void
use_network_uri (gboolean synchronous)
{
  GError *error = NULL;
  GSocketAddressEnumerator *enumerator;
  GSocketConnectable *connectable;

  connectable = g_network_address_parse_uri (info, 0, &error);

  if (error)
    {
      print_and_free_error (error);
      return;
    }

  enumerator = g_socket_connectable_proxy_enumerate (connectable);
  g_object_unref (connectable);

  printf ("Proxies for URI '%s' are:\n", info);
  run_with_enumerator (synchronous, enumerator);

  g_object_unref (enumerator);
}

static void
use_network_service (gboolean synchronous)
{
  GSocketAddressEnumerator *enumerator;
  GSocketConnectable *connectable = NULL;
  gchar **split;

  split = g_strsplit (info, "/", 3);

  if (split[0] && split[1] && split[2])
    connectable = g_network_service_new (split[0], split[1], split[2]);

  g_strfreev (split);

  if (connectable == NULL)
    {
       fprintf (stderr, "Bad 'srv/protocol/domain' parameter '%s'\n", info);
       return_value = 1;
       return;
    }

  enumerator = g_socket_connectable_proxy_enumerate (connectable);
  g_object_unref (connectable);

  printf ("Proxies for hostname and port '%s' are:\n", info);
  run_with_enumerator (synchronous, enumerator);

  g_object_unref (enumerator);
}

static void
_socket_connect_cb (GObject *object,
		    GAsyncResult *result,
		    gpointer user_data)
{
  GError *error = NULL;
  GMainLoop *loop = user_data;
  GSocketClient *client = G_SOCKET_CLIENT (object);
  GSocketConnection *connection;

  connection = g_socket_client_connect_to_uri_finish (client,
						      result,
						      &error);
  if (connection)
    {
      GSocketAddress *proxy_addr;
      proxy_addr = g_socket_connection_get_remote_address (connection, NULL);
      print_proxy_address (proxy_addr);
    }
  else
    {
      print_and_free_error (error);
    }

  g_main_loop_quit (loop);
}

static void
use_socket_client (gboolean synchronous)
{
  GError *error = NULL;
  GSocketClient *client;

  client = g_socket_client_new ();

  printf ("Proxies for URI '%s' are:\n", info);

  if (synchronous)
    {
      GSocketConnection *connection;
      GSocketAddress *proxy_addr;

      connection = g_socket_client_connect_to_uri (client,
						   info,
						   0,
      						   cancellable,
						   &error);

      if (connection)
	{
	  proxy_addr = g_socket_connection_get_remote_address (connection, NULL);
	  print_proxy_address (proxy_addr);
	}
      else
	{
	  print_and_free_error (error);
	}
    }
  else
    {
      GMainLoop *loop = g_main_loop_new (NULL, FALSE);

      g_socket_client_connect_to_uri_async (client,
					    info,
					    0,
					    cancellable,
					    _socket_connect_cb,
					    loop);

      g_main_loop_run (loop);
      g_main_loop_unref (loop);
    }

  g_object_unref (client);
}

typedef enum
{
  USE_RESOLVER,
  USE_ENUMERATOR,
#ifdef G_OS_UNIX
  USE_UNIX_SOCKET_ADDRESS,
#endif
  USE_INET_SOCKET_ADDRESS,
  USE_PROXY_ADDRESS,
  USE_NETWORK_ADDRESS,
  USE_NETWORK_URI,
  USE_NETWORK_SERVICE,
  USE_SOCKET_CLIENT,
} ProxyTestType;

gint
main (gint argc, gchar **argv)
{
  gboolean synchronous = FALSE;
  gboolean cancel = FALSE;
  ProxyTestType type = USE_RESOLVER;

  while (argc >= 2 && argv[1][0] == '-')
    {
      if (!strcmp (argv[1], "-s"))
        synchronous = TRUE;
      else if (!strcmp (argv[1], "-c"))
        cancel = TRUE;
      else if (!strcmp (argv[1], "-e"))
        type = USE_ENUMERATOR;
      else if (!strcmp (argv[1], "-inet"))
        type = USE_INET_SOCKET_ADDRESS;
#ifdef G_OS_UNIX
      else if (!strcmp (argv[1], "-unix"))
        type = USE_UNIX_SOCKET_ADDRESS;
#endif
      else if (!strcmp (argv[1], "-proxyaddr"))
        type = USE_PROXY_ADDRESS;
      else if (!strcmp (argv[1], "-netaddr"))
        type = USE_NETWORK_ADDRESS;
      else if (!strcmp (argv[1], "-neturi"))
        type = USE_NETWORK_URI;
      else if (!strcmp (argv[1], "-netsrv"))
        type = USE_NETWORK_SERVICE;
      else if (!strcmp (argv[1], "-connect"))
        type = USE_SOCKET_CLIENT;
      else
	usage ();

      argv++;
      argc--;
    }

  if (argc != 2)
    usage ();

  /* Save URI for asynchronous callback */
  info = argv[1];

  if (cancel)
    {
      cancellable = g_cancellable_new ();
      g_cancellable_cancel (cancellable);
    }

  switch (type)
    {
    case USE_RESOLVER:
      use_resolver (synchronous);
      break;
    case USE_ENUMERATOR:
      use_enumerator (synchronous);
      break;
    case USE_INET_SOCKET_ADDRESS:
      use_inet_address (synchronous);
      break;
#ifdef G_OS_UNIX
    case USE_UNIX_SOCKET_ADDRESS:
      use_unix_address (synchronous);
      break;
#endif
    case USE_PROXY_ADDRESS:
      use_proxy_address (synchronous);
      break;
    case USE_NETWORK_ADDRESS:
      use_network_address (synchronous);
      break;
    case USE_NETWORK_URI:
      use_network_uri (synchronous);
      break;
    case USE_NETWORK_SERVICE:
      use_network_service (synchronous);
      break;
    case USE_SOCKET_CLIENT:
      use_socket_client (synchronous);
      break;
    }

  return return_value;
}
