/*
 * unity-webapps-dpkg-available-application.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 "unity-webapps-dpkg-available-application.h"

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

struct _UnityWebappsDpkgAvailableApplicationPrivate {
  UnityWebappsPackageMechanism *package_mechanism;
  gchar *name;
  gchar *application_name;
  gchar *application_domain;
};

enum {
  PROP_0,
  PROP_NAME,
  PROP_APPLICATION_NAME,
  PROP_APPLICATION_DOMAIN,
  PROP_PACKAGE_MECHANISM
};




G_DEFINE_TYPE(UnityWebappsDpkgAvailableApplication, unity_webapps_dpkg_available_application, UNITY_WEBAPPS_TYPE_AVAILABLE_APPLICATION)

#define UNITY_WEBAPPS_DPKG_AVAILABLE_APPLICATION_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), UNITY_WEBAPPS_TYPE_DPKG_AVAILABLE_APPLICATION, UnityWebappsDpkgAvailableApplicationPrivate))

static void
unity_webapps_dpkg_available_application_get_property (GObject *object,
					     guint prop_id,
					     GValue *value,
					     GParamSpec *pspec)
{
  UnityWebappsDpkgAvailableApplication *app;
  
  app = UNITY_WEBAPPS_DPKG_AVAILABLE_APPLICATION (object);
  
  switch (prop_id)
    {
    case PROP_NAME:
      g_value_set_string (value, app->priv->name);
      break;
    case PROP_APPLICATION_DOMAIN:
      g_value_set_string (value, app->priv->application_domain);
      break;
    case PROP_APPLICATION_NAME:
      g_value_set_string (value, app->priv->application_name);
      break;
    case PROP_PACKAGE_MECHANISM:
      g_value_set_object (value, app->priv->package_mechanism);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
unity_webapps_dpkg_available_application_set_property (GObject *object,
						       guint prop_id,
						       const GValue *value,
						       GParamSpec *pspec)
{
  UnityWebappsDpkgAvailableApplication *app;
  
  app = UNITY_WEBAPPS_DPKG_AVAILABLE_APPLICATION (object);
  
  switch (prop_id)
    {
    case PROP_NAME:
      g_return_if_fail (app->priv->name == NULL);
      app->priv->name = g_value_dup_string (value);
      break;
    case PROP_APPLICATION_NAME:
      g_return_if_fail (app->priv->application_name == NULL);
      app->priv->application_name = g_value_dup_string (value);
      break;
    case PROP_APPLICATION_DOMAIN:
      g_return_if_fail (app->priv->application_domain == NULL);
      app->priv->application_domain = g_value_dup_string (value);
      break;
    case PROP_PACKAGE_MECHANISM:
      g_return_if_fail (app->priv->package_mechanism == NULL);
      app->priv->package_mechanism = (UnityWebappsPackageMechanism *)g_value_dup_object (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

typedef struct _dpkg_install_query_data {
  UnityWebappsAvailableApplication *application;
  UnityWebappsAvailableApplicationInstalledQueryCallback callback;
  gpointer user_data;
} dpkg_install_query_data;

static void
dpkg_available_application_package_status_ready (UnityWebappsPackageMechanism *mechanism,
						 const gchar *name,
						 UnityWebappsPackageStatus status,
						 gpointer user_data)
{
  dpkg_install_query_data *data;
  gboolean installed;
  
  data = (dpkg_install_query_data *)user_data;
  
  installed = FALSE;
  
  if (status == UNITY_WEBAPPS_PACKAGE_STATUS_INSTALLED)
    {
      installed = TRUE;
    }
  
  data->callback (data->application, installed, data->user_data);
  
  g_free (data);
}


static void
dpkg_available_application_get_is_installed (UnityWebappsAvailableApplication *available_application,
					     UnityWebappsAvailableApplicationInstalledQueryCallback callback,
					     gpointer user_data)
{
  UnityWebappsDpkgAvailableApplication *self;
  dpkg_install_query_data *query_data;

  self = UNITY_WEBAPPS_DPKG_AVAILABLE_APPLICATION (available_application);
  
  query_data = g_malloc0 (sizeof(dpkg_install_query_data));
  query_data->application = available_application;
  query_data->callback = callback;
  query_data->user_data = user_data;
  
  unity_webapps_package_mechanism_get_package_status (self->priv->package_mechanism,
						      self->priv->name,
						      dpkg_available_application_package_status_ready,
						      query_data);
}

static const gchar *
dpkg_available_application_get_name (UnityWebappsAvailableApplication *available_application)
{
  UnityWebappsDpkgAvailableApplication *self;
  
  self = UNITY_WEBAPPS_DPKG_AVAILABLE_APPLICATION (available_application);
  
  return self->priv->name;
}

static const gchar *
dpkg_available_application_get_application_name (UnityWebappsAvailableApplication *available_application)
{
  UnityWebappsDpkgAvailableApplication *self;
  
  self = UNITY_WEBAPPS_DPKG_AVAILABLE_APPLICATION (available_application);
  
  return self->priv->application_name;
}

static const gchar *
dpkg_available_application_get_application_domain (UnityWebappsAvailableApplication *available_application)
{
  UnityWebappsDpkgAvailableApplication *self;
  
  self = UNITY_WEBAPPS_DPKG_AVAILABLE_APPLICATION (available_application);
  
  return self->priv->application_domain;
}

static void
unity_webapps_dpkg_available_application_finalize (GObject *object)
{
  UnityWebappsDpkgAvailableApplication *self;
  
  self = UNITY_WEBAPPS_DPKG_AVAILABLE_APPLICATION (object);

  if (self->priv->name)
    {
      g_free (self->priv->name);
    }
  if (self->priv->application_name)
    {
      g_free (self->priv->application_name);
    }
  if (self->priv->application_domain)
    {
      g_free (self->priv->application_domain);
    }
  
  g_object_unref (G_OBJECT (self->priv->package_mechanism));
}

static void
unity_webapps_dpkg_available_application_class_init (UnityWebappsDpkgAvailableApplicationClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  UnityWebappsAvailableApplicationClass *available_application_class = UNITY_WEBAPPS_AVAILABLE_APPLICATION_CLASS (klass);
  
  object_class->finalize = unity_webapps_dpkg_available_application_finalize;
  object_class->get_property = unity_webapps_dpkg_available_application_get_property;
  object_class->set_property = unity_webapps_dpkg_available_application_set_property;

  available_application_class->get_name = dpkg_available_application_get_name;
  available_application_class->get_application_name = dpkg_available_application_get_application_name;
  available_application_class->get_application_domain = dpkg_available_application_get_application_domain;
  available_application_class->get_is_installed = dpkg_available_application_get_is_installed;
  
  g_object_class_install_property (object_class, PROP_NAME,
				   g_param_spec_string ("name",
							"Name",
							"The Package Name",
							NULL,
							G_PARAM_READWRITE | 
							G_PARAM_STATIC_STRINGS |
							G_PARAM_CONSTRUCT_ONLY));

  g_object_class_install_property (object_class, PROP_APPLICATION_NAME,
				   g_param_spec_string ("application-name",
							"Application Name",
							"The Application Name",
							NULL,
							G_PARAM_READWRITE | 
							G_PARAM_STATIC_STRINGS |
							G_PARAM_CONSTRUCT_ONLY));

  g_object_class_install_property (object_class, PROP_APPLICATION_DOMAIN,
				   g_param_spec_string ("application-domain",
							"Application Domain",
							"The Application Domain",
							NULL,
							G_PARAM_READWRITE | 
							G_PARAM_STATIC_STRINGS |
							G_PARAM_CONSTRUCT_ONLY));

  
  g_object_class_install_property (object_class, PROP_PACKAGE_MECHANISM,
				   g_param_spec_object ("package-mechanism",
							"Package Mechanism",
							"Mechanism to use for external packaging actions",
							UNITY_WEBAPPS_TYPE_PACKAGE_MECHANISM,
							G_PARAM_READWRITE |
							G_PARAM_STATIC_STRINGS |
							G_PARAM_CONSTRUCT_ONLY));

  g_type_class_add_private (object_class, sizeof(UnityWebappsDpkgAvailableApplicationPrivate));
}

static void
unity_webapps_dpkg_available_application_init (UnityWebappsDpkgAvailableApplication *self)
{
  self->priv = UNITY_WEBAPPS_DPKG_AVAILABLE_APPLICATION_GET_PRIVATE (self);
  
  self->priv->name = NULL;
  self->priv->package_mechanism = NULL;
}



UnityWebappsAvailableApplication *
unity_webapps_dpkg_available_application_new (const gchar *name, const gchar *application_name,
					      const gchar *application_domain,
					      UnityWebappsPackageMechanism *package_mechanism)
{
  return UNITY_WEBAPPS_AVAILABLE_APPLICATION (g_object_new (UNITY_WEBAPPS_TYPE_DPKG_AVAILABLE_APPLICATION, 
							    "name", name, 
							    "application-name", application_name,
							    "application-domain", application_domain,
							    "package-mechanism", package_mechanism,
							    NULL));
}

typedef struct _webapp_dpkg_install_data {
  UnityWebappsDpkgAvailableApplication *application;
  UnityWebappsAvailableApplicationInstalledQueryCallback callback;
  gpointer user_data;
} webapp_dpkg_install_data;

static void
dpkg_available_application_installed (UnityWebappsPackageMechanism *mechanism,
				      const gchar *name,
				      UnityWebappsPackageStatus status,
				      gpointer user_data)
{
  webapp_dpkg_install_data *data;
  gboolean installed;
  
  data = (webapp_dpkg_install_data *)user_data;
  
  installed = FALSE;
  
  if (status == UNITY_WEBAPPS_PACKAGE_STATUS_INSTALLED)
    {
      installed = TRUE;
    }
  
  data->callback ((UnityWebappsAvailableApplication *)data->application, installed, data->user_data);
  g_free (data);
}

gboolean
unity_webapps_dpkg_available_application_install (UnityWebappsDpkgAvailableApplication *application,
						  UnityWebappsAvailableApplicationInstalledQueryCallback callback,
						  gpointer user_data)
{
  webapp_dpkg_install_data *data;
  
  data = g_malloc0 (sizeof (webapp_dpkg_install_data));
  data->application = application;
  data->callback = callback;
  data->user_data = user_data;
  
  unity_webapps_package_mechanism_install_package (application->priv->package_mechanism, application->priv->name,
						   dpkg_available_application_installed,
						   data);
 
  return TRUE;
}

