/* GLib testing framework examples and tests
 *
 * Copyright 2012 Red Hat, Inc.
 *
 * 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/>.
 */

#include <string.h>

#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_34
#include <gio/gio.h>

/* Overview:
 *
 * We have an echo server, two proxy servers, two GProxy
 * implementations, and two GProxyResolver implementations.
 *
 * The echo server runs at @server.server_addr (on
 * @server.server_port).
 *
 * The two proxy servers, A and B, run on @proxy_a.port and
 * @proxy_b.port, with @proxy_a.uri and @proxy_b.uri pointing to them.
 * The "negotiation" with the two proxies is just sending the single
 * letter "a" or "b" and receiving it back in uppercase; the proxy
 * then connects to @server_addr.
 *
 * Proxy A supports "alpha://" URIs, and does not support hostname
 * resolution, and Proxy B supports "beta://" URIs, and does support
 * hostname resolution (but it just ignores the hostname and always
 * connects to @server_addr anyway).
 *
 * The default GProxyResolver (GTestProxyResolver) looks at its URI
 * and returns [ "direct://" ] for "simple://" URIs, and [
 * proxy_a.uri, proxy_b.uri ] for other URIs. The other GProxyResolver
 * (GTestAltProxyResolver) always returns [ proxy_a.uri ].
 */

typedef struct {
  gchar *proxy_command;
  gchar *supported_protocol;

  GSocket *server;
  GThread *thread;
  GCancellable *cancellable;
  gchar *uri;
  gushort port;

  GSocket *client_sock, *server_sock;
  GMainLoop *loop;

  GError *last_error;
} ProxyData;

static ProxyData proxy_a, proxy_b;

typedef struct {
  GSocket *server;
  GThread *server_thread;
  GCancellable *cancellable;
  GSocketAddress *server_addr;
  gushort server_port;
} ServerData;

static ServerData server;

static gchar **last_proxies;

static GSocketClient *client;


/**************************************/
/* Test GProxyResolver implementation */
/**************************************/

typedef struct {
  GObject parent_instance;
} GTestProxyResolver;

typedef struct {
  GObjectClass parent_class;
} GTestProxyResolverClass;

static void g_test_proxy_resolver_iface_init (GProxyResolverInterface *iface);

static GType _g_test_proxy_resolver_get_type (void);
#define g_test_proxy_resolver_get_type _g_test_proxy_resolver_get_type
G_DEFINE_TYPE_WITH_CODE (GTestProxyResolver, g_test_proxy_resolver, G_TYPE_OBJECT,
			 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
						g_test_proxy_resolver_iface_init)
			 g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME,
							 g_define_type_id,
							 "test",
							 0))

static void
g_test_proxy_resolver_init (GTestProxyResolver *resolver)
{
}

static gboolean
g_test_proxy_resolver_is_supported (GProxyResolver *resolver)
{
  return TRUE;
}

static gchar **
g_test_proxy_resolver_lookup (GProxyResolver  *resolver,
			      const gchar     *uri,
			      GCancellable    *cancellable,
			      GError         **error)
{
  gchar **proxies;

  g_assert (last_proxies == NULL);

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return NULL;

  proxies = g_new (gchar *, 3);

  if (!strncmp (uri, "simple://", 4))
    {
      proxies[0] = g_strdup ("direct://");
      proxies[1] = NULL;
    }
  else
    {
      /* Proxy A can only deal with "alpha://" URIs, not
       * "beta://", but we always return both URIs
       * anyway so we can test error handling when the first
       * fails.
       */
      proxies[0] = g_strdup (proxy_a.uri);
      proxies[1] = g_strdup (proxy_b.uri);
      proxies[2] = NULL;
    }

  last_proxies = g_strdupv (proxies);

  return proxies;
}

static void
g_test_proxy_resolver_lookup_async (GProxyResolver      *resolver,
				    const gchar         *uri,
				    GCancellable        *cancellable,
				    GAsyncReadyCallback  callback,
				    gpointer             user_data)
{
  GError *error = NULL;
  GTask *task;
  gchar **proxies;

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

  task = g_task_new (resolver, NULL, callback, user_data);
  if (proxies == NULL)
    g_task_return_error (task, error);
  else
    g_task_return_pointer (task, proxies, (GDestroyNotify) g_strfreev);

  g_object_unref (task);
}

static gchar **
g_test_proxy_resolver_lookup_finish (GProxyResolver     *resolver,
				     GAsyncResult       *result,
				     GError            **error)
{
  return g_task_propagate_pointer (G_TASK (result), error);
}

static void
g_test_proxy_resolver_class_init (GTestProxyResolverClass *resolver_class)
{
}

static void
g_test_proxy_resolver_iface_init (GProxyResolverInterface *iface)
{
  iface->is_supported = g_test_proxy_resolver_is_supported;
  iface->lookup = g_test_proxy_resolver_lookup;
  iface->lookup_async = g_test_proxy_resolver_lookup_async;
  iface->lookup_finish = g_test_proxy_resolver_lookup_finish;
}

/****************************/
/* Alternate GProxyResolver */
/****************************/

typedef GTestProxyResolver GTestAltProxyResolver;
typedef GTestProxyResolverClass GTestAltProxyResolverClass;

static void g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface *iface);

static GType _g_test_alt_proxy_resolver_get_type (void);
#define g_test_alt_proxy_resolver_get_type _g_test_alt_proxy_resolver_get_type
G_DEFINE_TYPE_WITH_CODE (GTestAltProxyResolver, g_test_alt_proxy_resolver, g_test_proxy_resolver_get_type (),
			 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
						g_test_alt_proxy_resolver_iface_init);
                         )

static void
g_test_alt_proxy_resolver_init (GTestProxyResolver *resolver)
{
}

static gchar **
g_test_alt_proxy_resolver_lookup (GProxyResolver  *resolver,
                                  const gchar     *uri,
                                  GCancellable    *cancellable,
                                  GError         **error)
{
  gchar **proxies;

  proxies = g_new (gchar *, 2);

  proxies[0] = g_strdup (proxy_a.uri);
  proxies[1] = NULL;

  last_proxies = g_strdupv (proxies);

  return proxies;
}

static void
g_test_alt_proxy_resolver_class_init (GTestProxyResolverClass *resolver_class)
{
}

static void
g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface *iface)
{
  iface->lookup = g_test_alt_proxy_resolver_lookup;
}


/****************************************/
/* Test proxy implementation base class */
/****************************************/

typedef struct {
  GObject parent;

  ProxyData *proxy_data;
} GProxyBase;

typedef struct {
  GObjectClass parent_class;
} GProxyBaseClass;

static GType _g_proxy_base_get_type (void);
#define g_proxy_base_get_type _g_proxy_base_get_type
G_DEFINE_ABSTRACT_TYPE (GProxyBase, g_proxy_base, G_TYPE_OBJECT)

static void
g_proxy_base_init (GProxyBase *proxy)
{
}

static GIOStream *
g_proxy_base_connect (GProxy            *proxy,
		      GIOStream         *io_stream,
		      GProxyAddress     *proxy_address,
		      GCancellable      *cancellable,
		      GError           **error)
{
  ProxyData *data = ((GProxyBase *) proxy)->proxy_data;
  const gchar *protocol;
  GOutputStream *ostream;
  GInputStream *istream;
  gchar response;

  g_assert_no_error (data->last_error);

  protocol = g_proxy_address_get_destination_protocol (proxy_address);
  if (strcmp (protocol, data->supported_protocol) != 0)
    {
      g_set_error_literal (&data->last_error,
			   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
			   "Unsupported protocol");
      goto fail;
    }

  ostream = g_io_stream_get_output_stream (io_stream);
  if (g_output_stream_write (ostream, data->proxy_command, 1, cancellable,
			     &data->last_error) != 1)
    goto fail;

  istream = g_io_stream_get_input_stream (io_stream);
  if (g_input_stream_read (istream, &response, 1, cancellable,
			   &data->last_error) != 1)
    goto fail;

  if (response != g_ascii_toupper (*data->proxy_command))
    {
      g_set_error_literal (&data->last_error,
			   G_IO_ERROR, G_IO_ERROR_FAILED,
			   "Failed");
      goto fail;
    }

  return g_object_ref (io_stream);

 fail:
  g_propagate_error (error, g_error_copy (data->last_error));
  return NULL;
}

static void
g_proxy_base_connect_async (GProxy               *proxy,
			    GIOStream            *io_stream,
			    GProxyAddress        *proxy_address,
			    GCancellable         *cancellable,
			    GAsyncReadyCallback   callback,
			    gpointer              user_data)
{
  GError *error = NULL;
  GTask *task;
  GIOStream *proxy_io_stream;

  task = g_task_new (proxy, NULL, callback, user_data);

  proxy_io_stream = g_proxy_connect (proxy, io_stream, proxy_address,
				     cancellable, &error);
  if (proxy_io_stream)
    g_task_return_pointer (task, proxy_io_stream, g_object_unref);
  else
    g_task_return_error (task, error);
  g_object_unref (task);
}

static GIOStream *
g_proxy_base_connect_finish (GProxy        *proxy,
			     GAsyncResult  *result,
			     GError       **error)
{
  return g_task_propagate_pointer (G_TASK (result), error);
}

static void
g_proxy_base_class_init (GProxyBaseClass *class)
{
}


/********************************************/
/* Test proxy implementation #1 ("Proxy A") */
/********************************************/

typedef GProxyBase GProxyA;
typedef GProxyBaseClass GProxyAClass;

static void g_proxy_a_iface_init (GProxyInterface *proxy_iface);

static GType _g_proxy_a_get_type (void);
#define g_proxy_a_get_type _g_proxy_a_get_type
G_DEFINE_TYPE_WITH_CODE (GProxyA, g_proxy_a, g_proxy_base_get_type (),
			 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
						g_proxy_a_iface_init)
			 g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
							 g_define_type_id,
							 "proxy-a",
							 0))

static void
g_proxy_a_init (GProxyA *proxy)
{
  ((GProxyBase *) proxy)->proxy_data = &proxy_a;
}

static gboolean
g_proxy_a_supports_hostname (GProxy *proxy)
{
  return FALSE;
}

static void
g_proxy_a_class_init (GProxyAClass *class)
{
}

static void
g_proxy_a_iface_init (GProxyInterface *proxy_iface)
{
  proxy_iface->connect = g_proxy_base_connect;
  proxy_iface->connect_async = g_proxy_base_connect_async;
  proxy_iface->connect_finish = g_proxy_base_connect_finish;
  proxy_iface->supports_hostname = g_proxy_a_supports_hostname;
}

/********************************************/
/* Test proxy implementation #2 ("Proxy B") */
/********************************************/

typedef GProxyBase GProxyB;
typedef GProxyBaseClass GProxyBClass;

static void g_proxy_b_iface_init (GProxyInterface *proxy_iface);

static GType _g_proxy_b_get_type (void);
#define g_proxy_b_get_type _g_proxy_b_get_type
G_DEFINE_TYPE_WITH_CODE (GProxyB, g_proxy_b, g_proxy_base_get_type (),
			 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
						g_proxy_b_iface_init)
			 g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
							 g_define_type_id,
							 "proxy-b",
							 0))

static void
g_proxy_b_init (GProxyB *proxy)
{
  ((GProxyBase *) proxy)->proxy_data = &proxy_b;
}

static gboolean
g_proxy_b_supports_hostname (GProxy *proxy)
{
  return TRUE;
}

static void
g_proxy_b_class_init (GProxyBClass *class)
{
}

static void
g_proxy_b_iface_init (GProxyInterface *proxy_iface)
{
  proxy_iface->connect = g_proxy_base_connect;
  proxy_iface->connect_async = g_proxy_base_connect_async;
  proxy_iface->connect_finish = g_proxy_base_connect_finish;
  proxy_iface->supports_hostname = g_proxy_b_supports_hostname;
}


/***********************************/
/* The proxy server implementation */
/***********************************/

static gboolean
proxy_bytes (GSocket      *socket,
	     GIOCondition  condition,
	     gpointer      user_data)
{
  ProxyData *proxy = user_data;
  gssize nread, nwrote, total;
  gchar buffer[8];
  GSocket *out_socket;
  GError *error = NULL;

  nread = g_socket_receive_with_blocking (socket, buffer, sizeof (buffer),
					  TRUE, NULL, &error);
  if (nread == -1)
    {
      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
      return FALSE;
    }
  else
    g_assert_no_error (error);

  if (nread == 0)
    {
      g_main_loop_quit (proxy->loop);
      return FALSE;
    }

  if (socket == proxy->client_sock)
    out_socket = proxy->server_sock;
  else
    out_socket = proxy->client_sock;

  for (total = 0; total < nread; total += nwrote)
    {
      nwrote = g_socket_send_with_blocking (out_socket,
					    buffer + total, nread - total,
					    TRUE, NULL, &error);
      g_assert_no_error (error);
    }

  return TRUE;
}

static gpointer
proxy_thread (gpointer user_data)
{
  ProxyData *proxy = user_data;
  GError *error = NULL;
  gssize nread, nwrote;
  gchar command[2] = { 0, 0 };
  GMainContext *context;
  GSource *read_source, *write_source;

  context = g_main_context_new ();
  proxy->loop = g_main_loop_new (context, FALSE);

  while (TRUE)
    {
      proxy->client_sock = g_socket_accept (proxy->server, proxy->cancellable, &error);
      if (!proxy->client_sock)
	{
	  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
          g_error_free (error);
	  break;
	}
      else
	g_assert_no_error (error);

      nread = g_socket_receive (proxy->client_sock, command, 1, NULL, &error);
      g_assert_no_error (error);

      if (nread == 0)
	{
	  g_clear_object (&proxy->client_sock);
	  continue;
	}

      g_assert_cmpint (nread, ==, 1);
      g_assert_cmpstr (command, ==, proxy->proxy_command);

      *command = g_ascii_toupper (*command);
      nwrote = g_socket_send (proxy->client_sock, command, 1, NULL, &error);
      g_assert_no_error (error);
      g_assert_cmpint (nwrote, ==, 1);

      proxy->server_sock = g_socket_new (G_SOCKET_FAMILY_IPV4,
					 G_SOCKET_TYPE_STREAM,
					 G_SOCKET_PROTOCOL_DEFAULT,
					 &error);
      g_assert_no_error (error);
      g_socket_connect (proxy->server_sock, server.server_addr, NULL, &error);
      g_assert_no_error (error);

      read_source = g_socket_create_source (proxy->client_sock, G_IO_IN, NULL);
      g_source_set_callback (read_source, (GSourceFunc)proxy_bytes, proxy, NULL);
      g_source_attach (read_source, context);

      write_source = g_socket_create_source (proxy->server_sock, G_IO_IN, NULL);
      g_source_set_callback (write_source, (GSourceFunc)proxy_bytes, proxy, NULL);
      g_source_attach (write_source, context);

      g_main_loop_run (proxy->loop);

      g_socket_close (proxy->client_sock, &error);
      g_assert_no_error (error);
      g_clear_object (&proxy->client_sock);

      g_socket_close (proxy->server_sock, &error);
      g_assert_no_error (error);
      g_clear_object (&proxy->server_sock);

      g_source_destroy (read_source);
      g_source_unref (read_source);
      g_source_destroy (write_source);
      g_source_unref (write_source);
    }

  g_main_loop_unref (proxy->loop);
  g_main_context_unref (context);

  g_object_unref (proxy->server);
  g_object_unref (proxy->cancellable);

  g_free (proxy->proxy_command);
  g_free (proxy->supported_protocol);
  g_free (proxy->uri);

  return NULL;
}

static void
create_proxy (ProxyData    *proxy,
	      gchar         proxy_protocol,
	      const gchar  *destination_protocol,
	      GCancellable *cancellable)
{
  GError *error = NULL;
  GSocketAddress *addr;
  GInetAddress *iaddr;

  proxy->proxy_command = g_strdup_printf ("%c", proxy_protocol);
  proxy->supported_protocol = g_strdup (destination_protocol);
  proxy->cancellable = g_object_ref (cancellable);

  proxy->server = g_socket_new (G_SOCKET_FAMILY_IPV4,
				G_SOCKET_TYPE_STREAM,
				G_SOCKET_PROTOCOL_DEFAULT,
				&error);
  g_assert_no_error (error);

  iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
  addr = g_inet_socket_address_new (iaddr, 0);
  g_object_unref (iaddr);

  g_socket_bind (proxy->server, addr, TRUE, &error);
  g_assert_no_error (error);
  g_object_unref (addr);

  addr = g_socket_get_local_address (proxy->server, &error);
  proxy->port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
  proxy->uri = g_strdup_printf ("proxy-%c://127.0.0.1:%u",
				g_ascii_tolower (proxy_protocol),
				proxy->port);
  g_object_unref (addr);

  g_socket_listen (proxy->server, &error);
  g_assert_no_error (error);

  proxy->thread = g_thread_new ("proxy", proxy_thread, proxy);
}



/**************************/
/* The actual echo server */
/**************************/

static gpointer
echo_server_thread (gpointer user_data)
{
  ServerData *data = user_data;
  GSocket *sock;
  GError *error = NULL;
  gssize nread, nwrote;
  gchar buf[128];

  while (TRUE)
    {
      sock = g_socket_accept (data->server, data->cancellable, &error);
      if (!sock)
	{
	  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
          g_error_free (error);
	  break;
	}
      else
	g_assert_no_error (error);

      while (TRUE)
	{
	  nread = g_socket_receive (sock, buf, sizeof (buf), NULL, &error);
	  g_assert_no_error (error);
	  g_assert_cmpint (nread, >=, 0);

	  if (nread == 0)
	    break;

	  nwrote = g_socket_send (sock, buf, nread, NULL, &error);
	  g_assert_no_error (error);
	  g_assert_cmpint (nwrote, ==, nread);
	}

      g_socket_close (sock, &error);
      g_assert_no_error (error);
      g_object_unref (sock);
    }

  g_object_unref (data->server);
  g_object_unref (data->server_addr);
  g_object_unref (data->cancellable);

  return NULL;
}

static void
create_server (ServerData *data, GCancellable *cancellable)
{
  GError *error = NULL;
  GSocketAddress *addr;
  GInetAddress *iaddr;

  data->cancellable = g_object_ref (cancellable);

  data->server = g_socket_new (G_SOCKET_FAMILY_IPV4,
			       G_SOCKET_TYPE_STREAM,
			       G_SOCKET_PROTOCOL_DEFAULT,
			       &error);
  g_assert_no_error (error);

  g_socket_set_blocking (data->server, TRUE);
  iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
  addr = g_inet_socket_address_new (iaddr, 0);
  g_object_unref (iaddr);

  g_socket_bind (data->server, addr, TRUE, &error);
  g_assert_no_error (error);
  g_object_unref (addr);

  data->server_addr = g_socket_get_local_address (data->server, &error);
  g_assert_no_error (error);

  data->server_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (data->server_addr));

  g_socket_listen (data->server, &error);
  g_assert_no_error (error);

  data->server_thread = g_thread_new ("server", echo_server_thread, data);
}


/******************************************************************/
/* Now a GResolver implementation, so the can't-resolve test will */
/* pass even if you have an evil DNS-faking ISP.                  */
/******************************************************************/

typedef GResolver GFakeResolver;
typedef GResolverClass GFakeResolverClass;

static GType g_fake_resolver_get_type (void);
G_DEFINE_TYPE (GFakeResolver, g_fake_resolver, G_TYPE_RESOLVER)

static void
g_fake_resolver_init (GFakeResolver *gtr)
{
}

static GList *
g_fake_resolver_lookup_by_name (GResolver     *resolver,
				const gchar   *hostname,
				GCancellable  *cancellable,
				GError       **error)
{
  if (!strcmp (hostname, "example.com"))
    return g_list_prepend (NULL, g_inet_address_new_from_string ("127.0.0.1"));
  else
    {
      /* Anything else is expected to fail. */
      g_set_error (error,
                   G_RESOLVER_ERROR,
                   G_RESOLVER_ERROR_NOT_FOUND,
                   "Not found");
      return NULL;
    }
}

static void
g_fake_resolver_lookup_by_name_async (GResolver           *resolver,
				      const gchar         *hostname,
				      GCancellable        *cancellable,
				      GAsyncReadyCallback  callback,
				      gpointer             user_data)
{
  GTask *task;

  task = g_task_new (resolver, cancellable, callback, user_data);

  if (!strcmp (hostname, "example.com"))
    {
      GList *result;

      result = g_list_prepend (NULL, g_inet_address_new_from_string ("127.0.0.1"));
      g_task_return_pointer (task, result, (GDestroyNotify) g_resolver_free_addresses);
    }
  else
    {
      g_task_return_new_error (task,
                               G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND,
                               "Not found");
    }
  g_object_unref (task);
}

static void
g_fake_resolver_lookup_by_name_with_flags_async (GResolver               *resolver,
                                                 const gchar             *hostname,
                                                 GResolverNameLookupFlags flags,
                                                 GCancellable            *cancellable,
                                                 GAsyncReadyCallback      callback,
                                                 gpointer                 user_data)
{
  /* Note this isn't a real implementation as it ignores the flags */
  g_fake_resolver_lookup_by_name_async (resolver,
                                        hostname,
                                        cancellable,
                                        callback,
                                        user_data);
}

static GList *
g_fake_resolver_lookup_by_name_finish (GResolver            *resolver,
				       GAsyncResult         *result,
				       GError              **error)
{
  return g_task_propagate_pointer (G_TASK (result), error);
}

static void
g_fake_resolver_class_init (GFakeResolverClass *fake_class)
{
  GResolverClass *resolver_class = G_RESOLVER_CLASS (fake_class);

  resolver_class->lookup_by_name                   = g_fake_resolver_lookup_by_name;
  resolver_class->lookup_by_name_async             = g_fake_resolver_lookup_by_name_async;
  resolver_class->lookup_by_name_finish            = g_fake_resolver_lookup_by_name_finish;
  resolver_class->lookup_by_name_with_flags_async  = g_fake_resolver_lookup_by_name_with_flags_async;
  resolver_class->lookup_by_name_with_flags_finish = g_fake_resolver_lookup_by_name_finish;
}



/****************************************/
/* We made it! Now for the actual test! */
/****************************************/

static void
setup_test (gpointer fixture,
	    gconstpointer user_data)
{
}

static void
teardown_test (gpointer fixture,
	       gconstpointer user_data)
{
  if (last_proxies)
    {
      g_strfreev (last_proxies);
      last_proxies = NULL;
    }
  g_clear_error (&proxy_a.last_error);
  g_clear_error (&proxy_b.last_error);
}


static const gchar *testbuf = "0123456789abcdef";

static void
do_echo_test (GSocketConnection *conn)
{
  GIOStream *iostream = G_IO_STREAM (conn);
  GInputStream *istream = g_io_stream_get_input_stream (iostream);
  GOutputStream *ostream = g_io_stream_get_output_stream (iostream);
  gssize nread;
  gsize nwrote, total;
  gchar buf[128];
  GError *error = NULL;

  g_output_stream_write_all (ostream, testbuf, strlen (testbuf),
			     &nwrote, NULL, &error);
  g_assert_no_error (error);
  g_assert_cmpint (nwrote, ==, strlen (testbuf));

  for (total = 0; total < nwrote; total += nread)
    {
      nread = g_input_stream_read (istream,
				   buf + total, sizeof (buf) - total,
				   NULL, &error);
      g_assert_no_error (error);
      g_assert_cmpint (nread, >, 0);
    }

  buf[total] = '\0';
  g_assert_cmpstr (buf, ==, testbuf);
}

static void
async_got_conn (GObject      *source,
		GAsyncResult *result,
		gpointer      user_data)
{
  GSocketConnection **conn = user_data;
  GError *error = NULL;

  *conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (source),
					  result, &error);
  g_assert_no_error (error);
}

static void
async_got_error (GObject      *source,
		 GAsyncResult *result,
		 gpointer      user_data)
{
  GError **error = user_data;

  g_assert (error != NULL && *error == NULL);
  g_socket_client_connect_finish (G_SOCKET_CLIENT (source),
				  result, error);
  g_assert (*error != NULL);
}


static void
assert_direct (GSocketConnection *conn)
{
  GSocketAddress *addr;
  GError *error = NULL;

  g_assert_cmpint (g_strv_length (last_proxies), ==, 1);
  g_assert_cmpstr (last_proxies[0], ==, "direct://");
  g_assert_no_error (proxy_a.last_error);
  g_assert_no_error (proxy_b.last_error);

  addr = g_socket_connection_get_remote_address (conn, &error);
  g_assert_no_error (error);
  g_assert (addr != NULL && !G_IS_PROXY_ADDRESS (addr));
  g_object_unref (addr);

  addr = g_socket_connection_get_local_address (conn, &error);
  g_assert_no_error (error);
  g_object_unref (addr);

  g_assert (g_socket_connection_is_connected (conn));
}

static void
test_direct_sync (gpointer fixture,
		  gconstpointer user_data)
{
  GSocketConnection *conn;
  gchar *uri;
  GError *error = NULL;

  /* The simple:// URI should not require any proxy. */

  uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port);
  conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
  g_free (uri);
  g_assert_no_error (error);

  assert_direct (conn);
  do_echo_test (conn);
  g_object_unref (conn);
}

static void
test_direct_async (gpointer fixture,
		   gconstpointer user_data)
{
  GSocketConnection *conn;
  gchar *uri;

  /* The simple:// URI should not require any proxy. */
  uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port);
  conn = NULL;
  g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
					async_got_conn, &conn);
  g_free (uri);
  while (conn == NULL)
    g_main_context_iteration (NULL, TRUE);

  assert_direct (conn);
  do_echo_test (conn);
  g_object_unref (conn);
}

static void
assert_single (GSocketConnection *conn)
{
  GSocketAddress *addr;
  const gchar *proxy_uri;
  gushort proxy_port;
  GError *error = NULL;

  g_assert_cmpint (g_strv_length (last_proxies), ==, 2);
  g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri);
  g_assert_cmpstr (last_proxies[1], ==, proxy_b.uri);
  g_assert_no_error (proxy_a.last_error);
  g_assert_no_error (proxy_b.last_error);

  addr = g_socket_connection_get_remote_address (conn, &error);
  g_assert_no_error (error);
  g_assert (G_IS_PROXY_ADDRESS (addr));
  proxy_uri = g_proxy_address_get_uri (G_PROXY_ADDRESS (addr));
  g_assert_cmpstr (proxy_uri, ==, proxy_a.uri);
  proxy_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
  g_assert_cmpint (proxy_port, ==, proxy_a.port);

  g_object_unref (addr);
}

static void
test_single_sync (gpointer fixture,
		  gconstpointer user_data)
{
  GSocketConnection *conn;
  GError *error = NULL;
  gchar *uri;

  /* The alpha:// URI should be proxied via Proxy A */
  uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port);
  conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
  g_free (uri);
  g_assert_no_error (error);

  assert_single (conn);

  do_echo_test (conn);
  g_object_unref (conn);
}

static void
test_single_async (gpointer fixture,
		   gconstpointer user_data)
{
  GSocketConnection *conn;
  gchar *uri;

  /* The alpha:// URI should be proxied via Proxy A */
  uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port);
  conn = NULL;
  g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
					async_got_conn, &conn);
  g_free (uri);
  while (conn == NULL)
    g_main_context_iteration (NULL, TRUE);

  assert_single (conn);
  do_echo_test (conn);
  g_object_unref (conn);
}

static void
assert_multiple (GSocketConnection *conn)
{
  GSocketAddress *addr;
  const gchar *proxy_uri;
  gushort proxy_port;
  GError *error = NULL;

  g_assert_cmpint (g_strv_length (last_proxies), ==, 2);
  g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri);
  g_assert_cmpstr (last_proxies[1], ==, proxy_b.uri);
  g_assert_error (proxy_a.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
  g_assert_no_error (proxy_b.last_error);

  addr = g_socket_connection_get_remote_address (conn, &error);
  g_assert_no_error (error);
  g_assert (G_IS_PROXY_ADDRESS (addr));
  proxy_uri = g_proxy_address_get_uri (G_PROXY_ADDRESS (addr));
  g_assert_cmpstr (proxy_uri, ==, proxy_b.uri);
  proxy_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
  g_assert_cmpint (proxy_port, ==, proxy_b.port);

  g_object_unref (addr);
}

static void
test_multiple_sync (gpointer fixture,
		    gconstpointer user_data)
{
  GSocketConnection *conn;
  GError *error = NULL;
  gchar *uri;

  /* The beta:// URI should be proxied via Proxy B, after failing
   * via Proxy A.
   */
  uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port);
  conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
  g_free (uri);
  g_assert_no_error (error);

  assert_multiple (conn);
  do_echo_test (conn);
  g_object_unref (conn);
}

static void
test_multiple_async (gpointer fixture,
		     gconstpointer user_data)
{
  GSocketConnection *conn;
  gchar *uri;

  /* The beta:// URI should be proxied via Proxy B, after failing
   * via Proxy A.
   */
  uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port);
  conn = NULL;
  g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
					async_got_conn, &conn);
  g_free (uri);
  while (conn == NULL)
    g_main_context_iteration (NULL, TRUE);

  assert_multiple (conn);
  do_echo_test (conn);
  g_object_unref (conn);
}

static void
test_dns (gpointer fixture,
	  gconstpointer user_data)
{
  GSocketConnection *conn;
  GError *error = NULL;
  gchar *uri;

  /* The simple:// and alpha:// URIs should fail with a DNS error,
   * but the beta:// URI should succeed, because we pass it to
   * Proxy B without trying to resolve it first
   */

  /* simple */
  uri = g_strdup_printf ("simple://no-such-host.xx:%u", server.server_port);
  conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
  g_assert_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND);
  g_clear_error (&error);

  g_assert_no_error (proxy_a.last_error);
  g_assert_no_error (proxy_b.last_error);
  teardown_test (NULL, NULL);

  g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
					async_got_error, &error);
  while (error == NULL)
    g_main_context_iteration (NULL, TRUE);
  g_assert_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND);
  g_clear_error (&error);
  g_free (uri);

  g_assert_no_error (proxy_a.last_error);
  g_assert_no_error (proxy_b.last_error);
  teardown_test (NULL, NULL);

  /* alpha */
  uri = g_strdup_printf ("alpha://no-such-host.xx:%u", server.server_port);
  conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
  /* Since Proxy A fails, @client will try Proxy B too, which won't
   * load an alpha:// URI.
   */
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
  g_clear_error (&error);

  g_assert_no_error (proxy_a.last_error);
  g_assert_error (proxy_b.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
  teardown_test (NULL, NULL);

  g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
					async_got_error, &error);
  while (error == NULL)
    g_main_context_iteration (NULL, TRUE);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
  g_clear_error (&error);
  g_free (uri);

  g_assert_no_error (proxy_a.last_error);
  g_assert_error (proxy_b.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
  teardown_test (NULL, NULL);

  /* beta */
  uri = g_strdup_printf ("beta://no-such-host.xx:%u", server.server_port);
  conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
  g_assert_no_error (error);

  g_assert_no_error (proxy_a.last_error);
  g_assert_no_error (proxy_b.last_error);

  do_echo_test (conn);
  g_clear_object (&conn);
  teardown_test (NULL, NULL);

  g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
					async_got_conn, &conn);
  while (conn == NULL)
    g_main_context_iteration (NULL, TRUE);
  g_free (uri);

  g_assert_no_error (proxy_a.last_error);
  g_assert_no_error (proxy_b.last_error);

  do_echo_test (conn);
  g_clear_object (&conn);
  teardown_test (NULL, NULL);
}

static void
assert_override (GSocketConnection *conn)
{
  g_assert_cmpint (g_strv_length (last_proxies), ==, 1);
  g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri);

  if (conn)
    g_assert_no_error (proxy_a.last_error);
  else
    g_assert_error (proxy_a.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
}

static void
test_override (gpointer fixture,
               gconstpointer user_data)
{
  GProxyResolver *alt_resolver;
  GSocketConnection *conn;
  GError *error = NULL;
  gchar *uri;

  g_assert (g_socket_client_get_proxy_resolver (client) == g_proxy_resolver_get_default ());
  alt_resolver = g_object_new (g_test_alt_proxy_resolver_get_type (), NULL);
  g_socket_client_set_proxy_resolver (client, alt_resolver);
  g_assert (g_socket_client_get_proxy_resolver (client) == alt_resolver);

  /* Alt proxy resolver always returns Proxy A, so alpha:// should
   * succeed, and simple:// and beta:// should fail.
   */

  /* simple */
  uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port);
  conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
  g_clear_error (&error);
  assert_override (conn);
  teardown_test (NULL, NULL);

  g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
					async_got_error, &error);
  while (error == NULL)
    g_main_context_iteration (NULL, TRUE);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
  g_clear_error (&error);
  assert_override (conn);
  g_free (uri);
  teardown_test (NULL, NULL);

  /* alpha */
  uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port);
  conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
  g_assert_no_error (error);
  assert_override (conn);
  do_echo_test (conn);
  g_clear_object (&conn);
  teardown_test (NULL, NULL);

  conn = NULL;
  g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
					async_got_conn, &conn);
  while (conn == NULL)
    g_main_context_iteration (NULL, TRUE);
  assert_override (conn);
  do_echo_test (conn);
  g_clear_object (&conn);
  g_free (uri);
  teardown_test (NULL, NULL);

  /* beta */
  uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port);
  conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
  g_clear_error (&error);
  assert_override (conn);
  teardown_test (NULL, NULL);

  g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
					async_got_error, &error);
  while (error == NULL)
    g_main_context_iteration (NULL, TRUE);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
  g_clear_error (&error);
  assert_override (conn);
  g_free (uri);
  teardown_test (NULL, NULL);

  g_assert (g_socket_client_get_proxy_resolver (client) == alt_resolver);
  g_socket_client_set_proxy_resolver (client, NULL);
  g_assert (g_socket_client_get_proxy_resolver (client) == g_proxy_resolver_get_default ());
  g_object_unref (alt_resolver);
}

static void
assert_destination_port (GSocketAddressEnumerator *etor,
                         guint16                   port)
{
  GSocketAddress *addr;
  GProxyAddress *paddr;
  GError *error = NULL;

  while ((addr = g_socket_address_enumerator_next (etor, NULL, &error)))
    {
      g_assert_no_error (error);

      g_assert (G_IS_PROXY_ADDRESS (addr));
      paddr = G_PROXY_ADDRESS (addr);
      g_assert_cmpint (g_proxy_address_get_destination_port (paddr), ==, port);
      g_object_unref (addr);
    }
  g_assert_no_error (error);
}

static void
test_proxy_enumerator_ports (void)
{
  GSocketAddressEnumerator *etor;

  etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
                       "uri", "http://example.com/",
                       NULL);
  assert_destination_port (etor, 0);
  g_object_unref (etor);

  /* Have to call this to clear last_proxies so the next call to
   * g_test_proxy_resolver_lookup() won't assert.
   */
  teardown_test (NULL, NULL);

  etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
                       "uri", "http://example.com:8080/",
                       NULL);
  assert_destination_port (etor, 8080);
  g_object_unref (etor);

  teardown_test (NULL, NULL);

  etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
                       "uri", "http://example.com/",
                       "default-port", 80,
                       NULL);
  assert_destination_port (etor, 80);
  g_object_unref (etor);

  teardown_test (NULL, NULL);

  etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
                       "uri", "http://example.com:8080/",
                       "default-port", 80,
                       NULL);
  assert_destination_port (etor, 8080);
  g_object_unref (etor);

  teardown_test (NULL, NULL);
}

int
main (int   argc,
      char *argv[])
{
  GResolver *fake_resolver;
  GCancellable *cancellable;
  gint result;

  g_test_init (&argc, &argv, NULL);

  /* Register stuff. The dummy g_proxy_get_default_for_protocol() call
   * is to force _g_io_modules_ensure_extension_points_registered() to
   * get called, so we can then register a proxy resolver extension
   * point.
   */
  g_proxy_get_default_for_protocol ("foo");
  g_test_proxy_resolver_get_type ();
  g_proxy_a_get_type ();
  g_proxy_b_get_type ();
  g_setenv ("GIO_USE_PROXY_RESOLVER", "test", TRUE);

  fake_resolver = g_object_new (g_fake_resolver_get_type (), NULL);
  g_resolver_set_default (fake_resolver);

  cancellable = g_cancellable_new ();
  create_server (&server, cancellable);
  create_proxy (&proxy_a, 'a', "alpha", cancellable);
  create_proxy (&proxy_b, 'b', "beta", cancellable);

  client = g_socket_client_new ();
  g_assert_cmpint (g_socket_client_get_enable_proxy (client), ==, TRUE);

  g_test_add_vtable ("/proxy/direct_sync", 0, NULL, setup_test, test_direct_sync, teardown_test);
  g_test_add_vtable ("/proxy/direct_async", 0, NULL, setup_test, test_direct_async, teardown_test);
  g_test_add_vtable ("/proxy/single_sync", 0, NULL, setup_test, test_single_sync, teardown_test);
  g_test_add_vtable ("/proxy/single_async", 0, NULL, setup_test, test_single_async, teardown_test);
  g_test_add_vtable ("/proxy/multiple_sync", 0, NULL, setup_test, test_multiple_sync, teardown_test);
  g_test_add_vtable ("/proxy/multiple_async", 0, NULL, setup_test, test_multiple_async, teardown_test);
  g_test_add_vtable ("/proxy/dns", 0, NULL, setup_test, test_dns, teardown_test);
  g_test_add_vtable ("/proxy/override", 0, NULL, setup_test, test_override, teardown_test);
  g_test_add_func ("/proxy/enumerator-ports", test_proxy_enumerator_ports);

  result = g_test_run();

  g_object_unref (client);

  g_cancellable_cancel (cancellable);
  g_thread_join (proxy_a.thread);
  g_thread_join (proxy_b.thread);
  g_thread_join (server.server_thread);

  g_object_unref (cancellable);

  return result;
}
