/*
 * unity-webapps-application-loader.c
 * Copyright (C) Canonical LTD 2011
 *
 * Author: Robert Carr <racarr@canonical.com>
 * 
 unity-webapps 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 3 of the License, or
 * (at your option) any later version.
 * 
 * unity-webapps 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 program.  If not, see <http://www.gnu.org/licenses/>.";
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gstdio.h>
#include <gio/gio.h>

#include <polkit/polkit.h>

#include "../unity-webapps-debug.h"

#include "unity-webapps-policy-authorizer.h"

struct _UnityWebappsPolicyAuthorizerPrivate {
  PolkitAuthority *authority;
  PolkitSubject *policy_subject;
};

G_DEFINE_TYPE(UnityWebappsPolicyAuthorizer, unity_webapps_policy_authorizer, G_TYPE_OBJECT)

#define UNITY_WEBAPPS_POLICY_AUTHORIZER_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), UNITY_WEBAPPS_TYPE_POLICY_AUTHORIZER, UnityWebappsPolicyAuthorizerPrivate))

static void
unity_webapps_policy_authorizer_finalize (GObject *object)
{
  UnityWebappsPolicyAuthorizer *authorizer;

  authorizer = UNITY_WEBAPPS_POLICY_AUTHORIZER (object);
  
  g_object_unref (G_OBJECT (authorizer->priv->authority));
  g_object_unref (G_OBJECT (authorizer->priv->policy_subject));
}

static void
unity_webapps_policy_authorizer_class_init (UnityWebappsPolicyAuthorizerClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  
  object_class->finalize = unity_webapps_policy_authorizer_finalize;
  
  g_type_class_add_private (object_class, sizeof(UnityWebappsPolicyAuthorizerPrivate));
}


static void
unity_webapps_policy_authorizer_init (UnityWebappsPolicyAuthorizer *authorizer)
{
  GDBusConnection *system_bus;
  const gchar *unique_name;

  authorizer->priv = UNITY_WEBAPPS_POLICY_AUTHORIZER_GET_PRIVATE (authorizer);

  system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
  unique_name = g_dbus_connection_get_unique_name (system_bus);
  
  authorizer->priv->authority = polkit_authority_get_sync (NULL, NULL);
  authorizer->priv->policy_subject = polkit_system_bus_name_new (unique_name);
}

UnityWebappsPolicyAuthorizer *
unity_webapps_policy_authorizer_new ()
{
  return g_object_new (UNITY_WEBAPPS_TYPE_POLICY_AUTHORIZER, NULL);
}

typedef struct _webapp_authorization_data {
  UnityWebappsPolicyAuthorizer *authorizer;
  UnityWebappsPolicyAuthorizerCallback callback;

  gpointer user_data;
} webapp_authorization_data;

static void
policy_authorizer_authorization_callback (GObject *object,
					  GAsyncResult *res,
					  gpointer user_data)
{
  PolkitAuthorizationResult *result;
  webapp_authorization_data *data;
  GError *error;
  gboolean authorized;
  
  data = (webapp_authorization_data *)user_data;
  
  error = NULL;
  result = polkit_authority_check_authorization_finish (POLKIT_AUTHORITY (object), res, &error);
  
  authorized = FALSE;
  
  if (error != NULL)
    {
      g_critical ("Error checking authorization: %s\n", error->message);
      g_error_free (error);
    }
  else
    {
      authorized = polkit_authorization_result_get_is_authorized (result);
    }
  data->callback(data->authorizer, authorized, data->callback);

  g_free (data);
}

gboolean
unity_webapps_policy_authorizer_get_install_authorization (UnityWebappsPolicyAuthorizer *authorizer, UnityWebappsPolicyAuthorizerCallback callback,
							   gpointer user_data)
{
  webapp_authorization_data *data;
  
  data = g_malloc0 (sizeof (webapp_authorization_data));
  data->authorizer = authorizer;
  data->callback = callback;
  data->user_data = user_data;

  polkit_authority_check_authorization (authorizer->priv->authority,
					authorizer->priv->policy_subject,
					"org.debian.apt.install-or-remove-packages",
					NULL,
					POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
					NULL,
					policy_authorizer_authorization_callback, data);
  
  return TRUE;
}
