/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright 2016 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 "xdp-dbus.h"
#include "giomodule-priv.h"
#include "gportalsupport.h"
#include "gproxyresolverportal.h"

struct _GProxyResolverPortal {
  GObject parent_instance;

  GXdpProxyResolver *resolver;
  gboolean network_available;
};

static void g_proxy_resolver_portal_iface_init (GProxyResolverInterface *iface);

G_DEFINE_TYPE_WITH_CODE (GProxyResolverPortal, g_proxy_resolver_portal, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
                                                g_proxy_resolver_portal_iface_init)
                         _g_io_modules_ensure_extension_points_registered ();
                         g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME,
                                                         g_define_type_id,
                                                         "portal",
                                                         90))

static void
g_proxy_resolver_portal_init (GProxyResolverPortal *resolver)
{
  resolver->resolver = gxdp_proxy_resolver_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                                                   G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
                                                                   "org.freedesktop.portal.Desktop",
                                                                   "/org/freedesktop/portal/desktop",
                                                                   NULL,
                                                                   NULL);

  resolver->network_available = glib_network_available_in_sandbox ();
}

static gboolean
g_proxy_resolver_portal_is_supported (GProxyResolver *object)
{
  GProxyResolverPortal *resolver = G_PROXY_RESOLVER_PORTAL (object);
  char *name_owner;
  gboolean has_portal;

  if (!glib_should_use_portal () || !resolver->resolver)
    return FALSE;

  name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (resolver->resolver));
  has_portal = name_owner != NULL;
  g_free (name_owner);

  return has_portal;
}

static const char *no_proxy[2] = { "direct://", NULL };

static gchar **
g_proxy_resolver_portal_lookup (GProxyResolver *proxy_resolver,
                                const gchar     *uri,
                                GCancellable    *cancellable,
                                GError         **error)
{
  GProxyResolverPortal *resolver = G_PROXY_RESOLVER_PORTAL (proxy_resolver);
  char **proxy = NULL;

  if (!gxdp_proxy_resolver_call_lookup_sync (resolver->resolver,
                                             uri,
                                             &proxy,
                                             cancellable,
                                             error))
    return NULL;

  if (!resolver->network_available)
    {
      g_strfreev (proxy);
      proxy = g_strdupv ((gchar **)no_proxy);
    }

  return proxy;
}

static void
g_proxy_resolver_portal_lookup_async (GProxyResolver      *proxy_resolver,
                                      const gchar         *uri,
                                      GCancellable        *cancellable,
                                      GAsyncReadyCallback  callback,
                                      gpointer             user_data)
{
  GProxyResolverPortal *resolver = G_PROXY_RESOLVER_PORTAL (proxy_resolver);

  gxdp_proxy_resolver_call_lookup (resolver->resolver,
                                   uri,
                                   cancellable,
                                   callback,
                                   user_data);
}

static gchar **
g_proxy_resolver_portal_lookup_finish (GProxyResolver  *proxy_resolver,
                                       GAsyncResult    *result,
                                       GError         **error)
{
  GProxyResolverPortal *resolver = G_PROXY_RESOLVER_PORTAL (proxy_resolver);
  char **proxy = NULL;

  if (!gxdp_proxy_resolver_call_lookup_finish (resolver->resolver,
                                               &proxy,
                                               result,
                                               error))
    return NULL;

  if (!resolver->network_available)
    {
      g_strfreev (proxy);
      proxy = g_strdupv ((gchar **)no_proxy);
    }

  return proxy;
}

static void
g_proxy_resolver_portal_finalize (GObject *object)
{
  GProxyResolverPortal *resolver = G_PROXY_RESOLVER_PORTAL (object);

  g_clear_object (&resolver->resolver);

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

static void
g_proxy_resolver_portal_class_init (GProxyResolverPortalClass *resolver_class)
{
  GObjectClass *object_class;
 
  object_class = G_OBJECT_CLASS (resolver_class);
  object_class->finalize = g_proxy_resolver_portal_finalize;
}

static void
g_proxy_resolver_portal_iface_init (GProxyResolverInterface *iface)
{
  iface->is_supported = g_proxy_resolver_portal_is_supported;
  iface->lookup = g_proxy_resolver_portal_lookup;
  iface->lookup_async = g_proxy_resolver_portal_lookup_async;
  iface->lookup_finish = g_proxy_resolver_portal_lookup_finish;
}
