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

static GMainLoop *loop;

static gboolean
on_incoming(GSocketService    *service,
            GSocketConnection *connection,
            GObject           *source,
            gpointer           useless)
{
  gint fd;
  GSocket *socket;
  const gchar *test = "eoeo";
  const gchar *first = "First thing";
  gsize bytes_written;
  GError *error = NULL;

  if (!g_output_stream_write_all(g_io_stream_get_output_stream(G_IO_STREAM(connection)),
                            first,
                            strlen(first) + 1,
                            &bytes_written,
                            NULL,
                            &error))
  {
      g_printerr("there was a problem writing first: %s\n",
          error->message);
      g_error_free(error);
      return -1;
  }

  fd = g_socket_get_fd(g_socket_connection_get_socket(connection));
  socket = g_socket_new_from_fd(fd, &error);
  if (socket == NULL)
    {
      g_printerr("There was a problem creating the socket: %s\n",
                 error->message);
      g_error_free(error);
      return FALSE;
    }

  /* it blocks on this call */
  g_socket_send(socket, test, strlen(test) + 1, NULL, NULL);

  g_print("Everything ok\n");

  g_main_loop_quit(loop);

  return TRUE;
}

int
main ()
{
  GInetAddress *iaddr;
  GSocketAddress *saddr;
  GSocketAddress *bound_addr;
  GSocketService *service;
  GError *error = NULL;

  /* backend server on loopback */
  iaddr = g_inet_address_new_loopback(G_SOCKET_FAMILY_IPV4);
  saddr = g_inet_socket_address_new(iaddr, 10002);
  g_object_unref(iaddr);

  service = g_socket_service_new();
  if (!g_socket_listener_add_address(G_SOCKET_LISTENER(service),
                                     saddr,
                                     G_SOCKET_TYPE_STREAM,
                                     G_SOCKET_PROTOCOL_TCP,
                                     NULL,
                                     &bound_addr,
                                     &error))
    {
      g_printerr("Service failed: %s\n", error->message);
      g_error_free(error);
      g_object_unref(saddr);
      g_object_unref(service);
      return -1;
    }

  g_object_unref(saddr);

  g_signal_connect(service, "incoming", G_CALLBACK(on_incoming), NULL);
  g_object_unref(service);

  loop = g_main_loop_new(NULL, FALSE);
  g_main_loop_run(loop);

  return 0;
}
