/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright 2011 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 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, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include "gnetworkmonitorbase.h"
#include "ginetaddress.h"
#include "ginetaddressmask.h"
#include "ginetsocketaddress.h"
#include "ginitable.h"
#include "gioerror.h"
#include "giomodule-priv.h"
#include "gnetworkmonitor.h"
#include "gsocketaddressenumerator.h"
#include "gsocketconnectable.h"
#include "glibintl.h"

static void g_network_monitor_base_iface_init (GNetworkMonitorInterface *iface);
static void g_network_monitor_base_initable_iface_init (GInitableIface *iface);

G_DEFINE_TYPE_WITH_CODE (GNetworkMonitorBase, g_network_monitor_base, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
                                                g_network_monitor_base_initable_iface_init)
                         G_IMPLEMENT_INTERFACE (G_TYPE_NETWORK_MONITOR,
                                                g_network_monitor_base_iface_init)
                         _g_io_modules_ensure_extension_points_registered ();
                         g_io_extension_point_implement (G_NETWORK_MONITOR_EXTENSION_POINT_NAME,
                                                         g_define_type_id,
                                                         "base",
                                                         0))

enum
{
  PROP_0,

  PROP_NETWORK_AVAILABLE
};

struct _GNetworkMonitorBasePrivate
{
  GPtrArray    *networks;
  gboolean      have_ipv4_default_route;
  gboolean      have_ipv6_default_route;
  gboolean      is_available;

  GMainContext *context;
  GSource      *network_changed_source;
  gboolean      initializing;
};

static guint network_changed_signal = 0;

static void queue_network_changed (GNetworkMonitorBase *monitor);

static void
g_network_monitor_base_init (GNetworkMonitorBase *monitor)
{
  monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor,
                                               G_TYPE_NETWORK_MONITOR_BASE,
                                               GNetworkMonitorBasePrivate);

  monitor->priv->networks = g_ptr_array_new_with_free_func (g_object_unref);
  monitor->priv->context = g_main_context_get_thread_default ();
  if (monitor->priv->context)
    g_main_context_ref (monitor->priv->context);

  monitor->priv->initializing = TRUE;
  queue_network_changed (monitor);
}

static void
g_network_monitor_base_constructed (GObject *object)
{
  GNetworkMonitorBase *monitor = G_NETWORK_MONITOR_BASE (object);

  if (G_OBJECT_TYPE (monitor) == G_TYPE_NETWORK_MONITOR_BASE)
    {
      GInetAddressMask *mask;

      /* We're the dumb base class, not a smarter subclass. So just
       * assume that the network is available.
       */
      mask = g_inet_address_mask_new_from_string ("0.0.0.0/0", NULL);
      g_network_monitor_base_add_network (monitor, mask);
      g_object_unref (mask);

      mask = g_inet_address_mask_new_from_string ("::/0", NULL);
      g_network_monitor_base_add_network (monitor, mask);
      g_object_unref (mask);
    }
}

static void
g_network_monitor_base_get_property (GObject    *object,
                                     guint       prop_id,
                                     GValue     *value,
                                     GParamSpec *pspec)
{
  GNetworkMonitorBase *monitor = G_NETWORK_MONITOR_BASE (object);

  switch (prop_id)
    {
      case PROP_NETWORK_AVAILABLE:
        g_value_set_boolean (value, monitor->priv->is_available);
        break;

      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }

}

static void
g_network_monitor_base_finalize (GObject *object)
{
  GNetworkMonitorBase *monitor = G_NETWORK_MONITOR_BASE (object);

  g_ptr_array_free (monitor->priv->networks, TRUE);
  if (monitor->priv->network_changed_source)
    {
      g_source_destroy (monitor->priv->network_changed_source);
      g_source_unref (monitor->priv->network_changed_source);
    }
  if (monitor->priv->context)
    g_main_context_unref (monitor->priv->context);

  G_OBJECT_CLASS (g_network_monitor_base_parent_class)->finalize (object);
}

static void
g_network_monitor_base_class_init (GNetworkMonitorBaseClass *monitor_class)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (monitor_class);

  g_type_class_add_private (monitor_class, sizeof (GNetworkMonitorBasePrivate));

  gobject_class->constructed  = g_network_monitor_base_constructed;
  gobject_class->get_property = g_network_monitor_base_get_property;
  gobject_class->finalize     = g_network_monitor_base_finalize;

  g_object_class_override_property (gobject_class, PROP_NETWORK_AVAILABLE, "network-available");
}

static gboolean
g_network_monitor_base_can_reach (GNetworkMonitor      *monitor,
                                  GSocketConnectable   *connectable,
                                  GCancellable         *cancellable,
                                  GError              **error)
{
  GNetworkMonitorBasePrivate *priv = G_NETWORK_MONITOR_BASE (monitor)->priv;
  GSocketAddressEnumerator *enumerator;
  GSocketAddress *addr;

  if (priv->have_ipv4_default_route &&
      priv->have_ipv6_default_route)
    return TRUE;

  if (priv->networks->len == 0)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE,
                           _("Network unreachable"));
      return FALSE;
    }

  enumerator = g_socket_connectable_proxy_enumerate (connectable);
  addr = g_socket_address_enumerator_next (enumerator, cancellable, error);
  if (!addr)
    {
      /* Either the user cancelled, or DNS resolution failed */
      g_object_unref (enumerator);
      return FALSE;
    }

  while (addr)
    {
      if (G_IS_INET_SOCKET_ADDRESS (addr))
        {
          GInetAddress *iaddr;
          int i;

          iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr));
          for (i = 0; i < priv->networks->len; i++)
            {
              if (g_inet_address_mask_matches (priv->networks->pdata[i], iaddr))
                {
                  g_object_unref (addr);
                  g_object_unref (enumerator);
                  return TRUE;
                }
            }
        }

      g_object_unref (addr);
      addr = g_socket_address_enumerator_next (enumerator, cancellable, error);
    }
  g_object_unref (enumerator);

  if (error && !*error)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE,
                           _("Host unreachable"));
    }
  return FALSE;
}

static void
g_network_monitor_base_iface_init (GNetworkMonitorInterface *monitor_iface)
{
  monitor_iface->can_reach = g_network_monitor_base_can_reach;

  network_changed_signal = g_signal_lookup ("network-changed", G_TYPE_NETWORK_MONITOR);
}

static gboolean
g_network_monitor_base_initable_init (GInitable     *initable,
                                      GCancellable  *cancellable,
                                      GError       **error)
{
  return TRUE;
}

static void
g_network_monitor_base_initable_iface_init (GInitableIface *iface)
{
  iface->init = g_network_monitor_base_initable_init;
}

static gboolean
emit_network_changed (gpointer user_data)
{
  GNetworkMonitorBase *monitor = user_data;
  gboolean is_available;

  g_object_ref (monitor);

  if (monitor->priv->initializing)
    monitor->priv->initializing = FALSE;
  else
    {
      is_available = (monitor->priv->have_ipv4_default_route ||
                      monitor->priv->have_ipv6_default_route);
      if (monitor->priv->is_available != is_available)
        {
          monitor->priv->is_available = is_available;
          g_object_notify (G_OBJECT (monitor), "network-available");
        }

      g_signal_emit (monitor, network_changed_signal, 0, is_available);
    }

  g_source_unref (monitor->priv->network_changed_source);
  monitor->priv->network_changed_source = NULL;

  g_object_unref (monitor);
  return FALSE;
}

static void
queue_network_changed (GNetworkMonitorBase *monitor)
{
  if (!monitor->priv->network_changed_source)
    {
      GSource *source;

      source = g_idle_source_new ();
      /* Use G_PRIORITY_HIGH_IDLE priority so that multiple
       * network-change-related notifications coming in at
       * G_PRIORITY_DEFAULT will get coalesced into one signal
       * emission.
       */
      g_source_set_priority (source, G_PRIORITY_HIGH_IDLE);
      g_source_set_callback (source, emit_network_changed, monitor, NULL);
      g_source_attach (source, monitor->priv->context);
      monitor->priv->network_changed_source = source;
    }

  /* Normally we wait to update is_available until we emit the signal,
   * to keep things consistent. But when we're first creating the
   * object, we want it to be correct right away.
   */
  if (monitor->priv->initializing)
    {
      monitor->priv->is_available = (monitor->priv->have_ipv4_default_route ||
                                     monitor->priv->have_ipv6_default_route);
    }
}

/**
 * g_network_monitor_base_add_network:
 * @monitor: the #GNetworkMonitorBase
 * @network: a #GInetAddressMask
 *
 * Adds @network to @monitor's list of available networks.
 *
 * Since: 2.32
 */
void
g_network_monitor_base_add_network (GNetworkMonitorBase *monitor,
                                    GInetAddressMask    *network)
{
  int i;

  for (i = 0; i < monitor->priv->networks->len; i++)
    {
      if (g_inet_address_mask_equal (monitor->priv->networks->pdata[i], network))
        return;
    }

  g_ptr_array_add (monitor->priv->networks, g_object_ref (network));
  if (g_inet_address_mask_get_length (network) == 0)
    {
      switch (g_inet_address_mask_get_family (network))
        {
        case G_SOCKET_FAMILY_IPV4:
          monitor->priv->have_ipv4_default_route = TRUE;
          break;
        case G_SOCKET_FAMILY_IPV6:
          monitor->priv->have_ipv6_default_route = TRUE;
          break;
        default:
          break;
        }
    }

  /* Don't emit network-changed when multicast-link-local routing
   * changes. This rather arbitrary decision is mostly because it
   * seems to change quite often...
   */
  if (g_inet_address_get_is_mc_link_local (g_inet_address_mask_get_address (network)))
    return;

  queue_network_changed (monitor);
}

/**
 * g_network_monitor_base_remove_network:
 * @monitor: the #GNetworkMonitorBase
 * @network: a #GInetAddressMask
 *
 * Removes @network from @monitor's list of available networks.
 *
 * Since: 2.32
 */
void
g_network_monitor_base_remove_network (GNetworkMonitorBase *monitor,
                                       GInetAddressMask    *network)
{
  int i;

  for (i = 0; i < monitor->priv->networks->len; i++)
    {
      if (g_inet_address_mask_equal (monitor->priv->networks->pdata[i], network))
        {
          g_ptr_array_remove_index_fast (monitor->priv->networks, i);

          if (g_inet_address_mask_get_length (network) == 0)
            {
              switch (g_inet_address_mask_get_family (network))
                {
                case G_SOCKET_FAMILY_IPV4:
                  monitor->priv->have_ipv4_default_route = FALSE;
                  break;
                case G_SOCKET_FAMILY_IPV6:
                  monitor->priv->have_ipv6_default_route = FALSE;
                  break;
                default:
                  break;
                }
            }

          queue_network_changed (monitor);
          return;
        }
    }
}

/**
 * g_network_monitor_base_set_networks:
 * @monitor: the #GNetworkMonitorBase
 * @networks: (array length=length): an array of #GInetAddressMask
 * @length: length of @networks
 *
 * Drops @monitor's current list of available networks and replaces
 * it with @networks.
 */
void
g_network_monitor_base_set_networks (GNetworkMonitorBase  *monitor,
                                     GInetAddressMask    **networks,
                                     gint                  length)
{
  int i;

  g_ptr_array_set_size (monitor->priv->networks, 0);
  monitor->priv->have_ipv4_default_route = FALSE;
  monitor->priv->have_ipv6_default_route = FALSE;

  for (i = 0; i < length; i++)
    g_network_monitor_base_add_network (monitor, networks[i]);
}
