/* 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, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"
#include "glib.h"
#include "glibintl.h"

#include "gnetworkmonitor.h"
#include "ginetaddress.h"
#include "ginetsocketaddress.h"
#include "ginitable.h"
#include "gioenumtypes.h"
#include "giomodule-priv.h"
#include "gtask.h"

/**
 * SECTION:gnetworkmonitor
 * @title: GNetworkMonitor
 * @short_description: Network status monitor
 * @include: gio/gio.h
 *
 * #GNetworkMonitor provides an easy-to-use cross-platform API
 * for monitoring network connectivity. On Linux, the implementation
 * is based on the kernel's netlink interface.
 */

/**
 * GNetworkMonitor:
 *
 * #GNetworkMonitor monitors the status of network connections and
 * indicates when a possibly-user-visible change has occurred.
 *
 * Since: 2.32
 */

/**
 * GNetworkMonitorInterface:
 * @g_iface: The parent interface.
 * @network_changed: the virtual function pointer for the
 *  GNetworkMonitor::network-changed signal.
 * @can_reach: the virtual function pointer for g_network_monitor_can_reach()
 * @can_reach_async: the virtual function pointer for
 *  g_network_monitor_can_reach_async()
 * @can_reach_finish: the virtual function pointer for
 *  g_network_monitor_can_reach_finish()
 *
 * The virtual function table for #GNetworkMonitor.
 *
 * Since: 2.32
 */

G_DEFINE_INTERFACE_WITH_CODE (GNetworkMonitor, g_network_monitor, G_TYPE_OBJECT,
                              g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_INITABLE);)


enum {
  NETWORK_CHANGED,
  LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = { 0 };

/**
 * g_network_monitor_get_default:
 *
 * Gets the default #GNetworkMonitor for the system.
 *
 * Returns: (transfer none): a #GNetworkMonitor
 *
 * Since: 2.32
 */
GNetworkMonitor *
g_network_monitor_get_default (void)
{
  return _g_io_module_get_default (G_NETWORK_MONITOR_EXTENSION_POINT_NAME,
                                   "GIO_USE_NETWORK_MONITOR",
                                   NULL);
}

/**
 * g_network_monitor_get_network_available:
 * @monitor: the #GNetworkMonitor
 *
 * Checks if the network is available. "Available" here means that the
 * system has a default route available for at least one of IPv4 or
 * IPv6. It does not necessarily imply that the public Internet is
 * reachable. See #GNetworkMonitor:network-available for more details.
 *
 * Returns: whether the network is available
 *
 * Since: 2.32
 */
gboolean
g_network_monitor_get_network_available (GNetworkMonitor *monitor)
{
  gboolean available = FALSE;

  g_object_get (G_OBJECT (monitor), "network-available", &available, NULL);
  return available;
}

/**
 * g_network_monitor_get_network_metered:
 * @monitor: the #GNetworkMonitor
 *
 * Checks if the network is metered.
 * See #GNetworkMonitor:network-metered for more details.
 *
 * Returns: whether the connection is metered
 *
 * Since: 2.46
 */
gboolean
g_network_monitor_get_network_metered (GNetworkMonitor *monitor)
{
  gboolean metered = FALSE;

  g_object_get (G_OBJECT (monitor), "network-metered", &metered, NULL);
  return metered;
}

/**
 * g_network_monitor_get_connectivity:
 * @monitor: the #GNetworkMonitor
 *
 * Gets a more detailed networking state than
 * g_network_monitor_get_network_available().
 *
 * If #GNetworkMonitor:network-available is %FALSE, then the
 * connectivity state will be %G_NETWORK_CONNECTIVITY_LOCAL.
 *
 * If #GNetworkMonitor:network-available is %TRUE, then the
 * connectivity state will be %G_NETWORK_CONNECTIVITY_FULL (if there
 * is full Internet connectivity), %G_NETWORK_CONNECTIVITY_LIMITED (if
 * the host has a default route, but appears to be unable to actually
 * reach the full Internet), or %G_NETWORK_CONNECTIVITY_PORTAL (if the
 * host is trapped behind a "captive portal" that requires some sort
 * of login or acknowledgement before allowing full Internet access).
 *
 * Note that in the case of %G_NETWORK_CONNECTIVITY_LIMITED and
 * %G_NETWORK_CONNECTIVITY_PORTAL, it is possible that some sites are
 * reachable but others are not. In this case, applications can
 * attempt to connect to remote servers, but should gracefully fall
 * back to their "offline" behavior if the connection attempt fails.
 *
 * Return value: the network connectivity state
 *
 * Since: 2.44
 */
GNetworkConnectivity
g_network_monitor_get_connectivity (GNetworkMonitor *monitor)
{
  GNetworkConnectivity connectivity;

  g_object_get (G_OBJECT (monitor), "connectivity", &connectivity, NULL);

  return connectivity;
}

/**
 * g_network_monitor_can_reach:
 * @monitor: a #GNetworkMonitor
 * @connectable: a #GSocketConnectable
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @error: return location for a #GError, or %NULL
 *
 * Attempts to determine whether or not the host pointed to by
 * @connectable can be reached, without actually trying to connect to
 * it.
 *
 * This may return %TRUE even when #GNetworkMonitor:network-available
 * is %FALSE, if, for example, @monitor can determine that
 * @connectable refers to a host on a local network.
 *
 * If @monitor believes that an attempt to connect to @connectable
 * will succeed, it will return %TRUE. Otherwise, it will return
 * %FALSE and set @error to an appropriate error (such as
 * %G_IO_ERROR_HOST_UNREACHABLE).
 *
 * Note that although this does not attempt to connect to
 * @connectable, it may still block for a brief period of time (eg,
 * trying to do multicast DNS on the local network), so if you do not
 * want to block, you should use g_network_monitor_can_reach_async().
 *
 * Returns: %TRUE if @connectable is reachable, %FALSE if not.
 *
 * Since: 2.32
 */
gboolean
g_network_monitor_can_reach (GNetworkMonitor     *monitor,
                             GSocketConnectable  *connectable,
                             GCancellable        *cancellable,
                             GError             **error)
{
  GNetworkMonitorInterface *iface;

  iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
  return iface->can_reach (monitor, connectable, cancellable, error);
}

static void
g_network_monitor_real_can_reach_async (GNetworkMonitor     *monitor,
                                        GSocketConnectable  *connectable,
                                        GCancellable        *cancellable,
                                        GAsyncReadyCallback  callback,
                                        gpointer             user_data)
{
  GTask *task;
  GError *error = NULL;

  task = g_task_new (monitor, cancellable, callback, user_data);
  g_task_set_source_tag (task, g_network_monitor_real_can_reach_async);

  if (g_network_monitor_can_reach (monitor, connectable, cancellable, &error))
    g_task_return_boolean (task, TRUE);
  else
    g_task_return_error (task, error);
  g_object_unref (task);
}

/**
 * g_network_monitor_can_reach_async:
 * @monitor: a #GNetworkMonitor
 * @connectable: a #GSocketConnectable
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @callback: (scope async): a #GAsyncReadyCallback to call when the
 *     request is satisfied
 * @user_data: (closure): the data to pass to callback function
 *
 * Asynchronously attempts to determine whether or not the host
 * pointed to by @connectable can be reached, without actually
 * trying to connect to it.
 *
 * For more details, see g_network_monitor_can_reach().
 *
 * When the operation is finished, @callback will be called.
 * You can then call g_network_monitor_can_reach_finish()
 * to get the result of the operation.
 */
void
g_network_monitor_can_reach_async (GNetworkMonitor     *monitor,
                                   GSocketConnectable  *connectable,
                                   GCancellable        *cancellable,
                                   GAsyncReadyCallback  callback,
                                   gpointer             user_data)
{
  GNetworkMonitorInterface *iface;

  iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
  iface->can_reach_async (monitor, connectable, cancellable, callback, user_data);
}

static gboolean
g_network_monitor_real_can_reach_finish (GNetworkMonitor  *monitor,
                                         GAsyncResult     *result,
                                         GError          **error)
{
  g_return_val_if_fail (g_task_is_valid (result, monitor), FALSE);

  return g_task_propagate_boolean (G_TASK (result), error);
}

/**
 * g_network_monitor_can_reach_finish:
 * @monitor: a #GNetworkMonitor
 * @result: a #GAsyncResult
 * @error: return location for errors, or %NULL
 *
 * Finishes an async network connectivity test.
 * See g_network_monitor_can_reach_async().
 *
 * Returns: %TRUE if network is reachable, %FALSE if not.
 */
gboolean
g_network_monitor_can_reach_finish (GNetworkMonitor     *monitor,
                                    GAsyncResult        *result,
                                    GError             **error)
{
  GNetworkMonitorInterface *iface;

  iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
  return iface->can_reach_finish (monitor, result, error);
}

static void
g_network_monitor_default_init (GNetworkMonitorInterface *iface)
{
  iface->can_reach_async  = g_network_monitor_real_can_reach_async;
  iface->can_reach_finish = g_network_monitor_real_can_reach_finish;

  /**
   * GNetworkMonitor::network-changed:
   * @monitor: a #GNetworkMonitor
   * @available: the current value of #GNetworkMonitor:network-available
   *
   * Emitted when the network configuration changes. If @available is
   * %TRUE, then some hosts may be reachable that were not reachable
   * before, while others that were reachable before may no longer be
   * reachable. If @available is %FALSE, then no remote hosts are
   * reachable.
   *
   * Since: 2.32
   */
  signals[NETWORK_CHANGED] =
    g_signal_new (I_("network-changed"),
                  G_TYPE_NETWORK_MONITOR,
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GNetworkMonitorInterface, network_changed),
                  NULL, NULL,
                  g_cclosure_marshal_VOID__BOOLEAN,
                  G_TYPE_NONE, 1,
                  G_TYPE_BOOLEAN);

  /**
   * GNetworkMonitor:network-available:
   *
   * Whether the network is considered available. That is, whether the
   * system has a default route for at least one of IPv4 or IPv6.
   *
   * Real-world networks are of course much more complicated than
   * this; the machine may be connected to a wifi hotspot that
   * requires payment before allowing traffic through, or may be
   * connected to a functioning router that has lost its own upstream
   * connectivity. Some hosts might only be accessible when a VPN is
   * active. Other hosts might only be accessible when the VPN is
   * not active. Thus, it is best to use g_network_monitor_can_reach()
   * or g_network_monitor_can_reach_async() to test for reachability
   * on a host-by-host basis. (On the other hand, when the property is
   * %FALSE, the application can reasonably expect that no remote
   * hosts at all are reachable, and should indicate this to the user
   * in its UI.)
   *
   * See also #GNetworkMonitor::network-changed.
   *
   * Since: 2.32
   */
  g_object_interface_install_property (iface,
                                       g_param_spec_boolean ("network-available",
                                                             P_("Network available"),
                                                             P_("Whether the network is available"),
                                                             FALSE,
                                                             G_PARAM_READABLE |
                                                             G_PARAM_STATIC_STRINGS));

  /**
   * GNetworkMonitor:network-metered:
   *
   * Whether the network is considered metered. That is, whether the
   * system has traffic flowing through the default connection that is
   * subject to limitations set by service providers. For example, traffic
   * might be billed by the amount of data transmitted, or there might be a
   * quota on the amount of traffic per month. This is typical with tethered
   * connections (3G and 4G) and in such situations, bandwidth intensive
   * applications may wish to avoid network activity where possible if it will
   * cost the user money or use up their limited quota.
   *
   * If more information is required about specific devices then the
   * system network management API should be used instead (for example,
   * NetworkManager or ConnMan).
   *
   * If this information is not available then no networks will be
   * marked as metered.
   *
   * See also #GNetworkMonitor:network-available.
   *
   * Since: 2.46
   */
  g_object_interface_install_property (iface,
                                       g_param_spec_boolean ("network-metered",
                                                             P_("Network metered"),
                                                             P_("Whether the network is metered"),
                                                             FALSE,
                                                             G_PARAM_READABLE |
                                                             G_PARAM_STATIC_STRINGS));

  /**
   * GNetworkMonitor:connectivity:
   *
   * More detailed information about the host's network connectivity.
   * See g_network_monitor_get_connectivity() and
   * #GNetworkConnectivity for more details.
   *
   * Since: 2.44
   */
  g_object_interface_install_property (iface,
                                       g_param_spec_enum ("connectivity",
                                                          P_("Network connectivity"),
                                                          P_("Level of network connectivity"),
                                                          G_TYPE_NETWORK_CONNECTIVITY,
                                                          G_NETWORK_CONNECTIVITY_FULL,
                                                          G_PARAM_READABLE |
                                                          G_PARAM_STATIC_STRINGS));
}
