/* gcc network-monitor.c $(pkg-config --cflags --libs glib-2.0
   gio-2.0) */

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

static const gchar *
gettime (void)
{
  static gchar buff[128];
  GTimeVal tv;
  gchar *str;

  g_get_current_time (&tv);
  str = g_time_val_to_iso8601 (&tv);
  strcpy (buff, str);
  g_free (str);

  return buff;
}

static void
check_reachable (GNetworkMonitor *network_monitor,
		 const gchar *func,
		 const gchar *address,
		 guint16 port)
{
  gboolean reachable;
  GSocketConnectable *connectable;
  GError *error = NULL;

  connectable = g_network_address_new (address, port);
  reachable = g_network_monitor_can_reach (network_monitor,
                                           connectable,
                                           NULL,
                                           &error);
  g_printf ("[%s] %s: %s:%d reachable:%d %s%s%s\n",
            gettime (),
            func,
            address,
            port,
            reachable,
            error ? "(" : "", error ? error->message : "", error ? ")" : "");
  g_clear_error (&error);
  g_object_unref (connectable);
}

static void
test_servers (GNetworkMonitor *network_monitor,
	      const gchar *from_where)
{
  check_reachable (network_monitor, from_where, "www.gnome.org", 80);
}

static void
network_changed_cb (GNetworkMonitor *network_monitor,
		    gboolean available)
{
  g_printf ("[%s] %s: available:%d\n", gettime (), __FUNCTION__, available);
  if (available)
    test_servers (network_monitor, __FUNCTION__);
}

static void
network_available_cb (GNetworkMonitor *network_monitor)
{
  gboolean available;

  available = g_network_monitor_get_network_available (network_monitor);
  g_print ("[%s] %s: available:%d\n", gettime (), __FUNCTION__, available);
  if (available)
    test_servers (network_monitor, __FUNCTION__);
}

int
main (int argc, char **argv)
{
  GMainLoop *main_loop;
  GNetworkMonitor *network_monitor;

  main_loop = g_main_loop_new (NULL, FALSE);
  network_monitor = g_network_monitor_get_default ();

  g_signal_connect (network_monitor,
                    "network-changed",
                    G_CALLBACK (network_changed_cb),
                    NULL);
  g_signal_connect (network_monitor,
                    "notify::network-available",
                    G_CALLBACK (network_available_cb),
                    NULL);

  network_available_cb (network_monitor);

  g_main_loop_run (main_loop);

  g_main_loop_unref (main_loop);

  return 0;
}
