#include "unity-webapps-application-info.h"
#include "unity-webapps-app-db.h"
#include "unity-webapps-resource-db.h"
#include <stdlib.h>
#include <stdio.h>

#include <gtk/gtk.h>

typedef struct _InfoTestFixture {
  UnityWebappsApplicationInfo *application_info;
} InfoTestFixture;

#define ICON_URL "data:image/png;base64,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"
#define INVALID_DATA_ICON_URL "data:foooasas;fa;sf'asf"
#define INVALID_DATA_ICON_MIME "data:foobar/la;base64, validbutwrongmimetype"

static void
setup_fixture_testts (InfoTestFixture *fixture, gconstpointer user_data)
{
  gchar *name, *domain, *icon_url;

  fixture->application_info = unity_webapps_application_info_new("Test", "test.ts", ICON_URL, NULL);
  
  g_object_get (fixture->application_info,
		"name", &name,
		"domain", &domain,
		"icon-url", &icon_url,
		NULL);

  g_assert_cmpstr(name, ==, "Test");
  g_assert_cmpstr(domain, ==, "test.ts");
  g_assert_cmpstr(icon_url, ==, ICON_URL);
  g_assert_cmpstr(name, ==, unity_webapps_application_info_get_name (fixture->application_info));
  g_assert_cmpstr(domain, ==, unity_webapps_application_info_get_domain (fixture->application_info));
  g_assert_cmpstr(icon_url, ==, unity_webapps_application_info_get_icon_url (fixture->application_info));

  unity_webapps_app_db_open ();
  unity_webapps_resource_db_open ();  
}

static void
setup_fixture_testts_write_failure (InfoTestFixture *fixture, gconstpointer user_data)
{
  fixture->application_info = unity_webapps_application_info_new("Test", "test.ts", ICON_URL, NULL);
  system("chmod 000 test-output-files");
}

static void
setup_fixture_testts_invalid_data_icon (InfoTestFixture *fixture, gconstpointer user_data)
{
  fixture->application_info = unity_webapps_application_info_new("Test", "test.ts", INVALID_DATA_ICON_URL, NULL);
}

static void
setup_fixture_testts_invalid_data_icon_mime (InfoTestFixture *fixture, gconstpointer user_data)
{
  fixture->application_info = unity_webapps_application_info_new("Test", "test.ts", INVALID_DATA_ICON_MIME, NULL);
}

static void
setup_fixture_testts_themed_icon (InfoTestFixture *fixture, gconstpointer user_data)
{
  fixture->application_info = unity_webapps_application_info_new("Test", "test.ts", "icon://Test-themed-application-icons", NULL);
}

static void
setup_fixture_testts_space_in_name (InfoTestFixture *fixture, gconstpointer user_data)
{
  fixture->application_info = unity_webapps_application_info_new("Test Space", "test.ts", ICON_URL, NULL);
}

static void
create_test_output_files_dir (gboolean copy_theme)
{
  system("mkdir test-output-files");
  if (copy_theme)
    {
      system("cp -R "TEST_SRCDIR"/unity-webapps-applications test-output-files/unity-webapps-applications");
      system("chmod -R 777 test-output-files/unity-webapps-applications");
    }
}

static void
teardown_fixture (InfoTestFixture *fixture, gconstpointer user_data)
{
  g_object_unref (G_OBJECT (fixture->application_info));
  system("chmod 777 test-output-files");
  system("rm -rf test-output-files");
  create_test_output_files_dir (TRUE);
}

static void
setup_unity_webapps_environment ()
{
  system("rm -rf test-output-files");
  create_test_output_files_dir (TRUE);

  g_setenv("UNITY_WEBAPPS_CONTEXT_ICON_DIR", "test-output-files", TRUE);
  g_setenv("UNITY_WEBAPPS_CONTEXT_ICON_THEME_DIR", "test-output-files", TRUE);
  g_setenv("UNITY_WEBAPPS_CONTEXT_APPLICATION_DIR", "test-output-files", TRUE);
  g_setenv("UNITY_WEBAPPS_CONTEXT_RESOURCE_DIR", "test-output-files", TRUE);
  g_setenv("UNITY_WEBAPPS_CONTEXT_USER_DIR", "test-output-files", TRUE);
  
  unity_webapps_app_db_open ();
  unity_webapps_resource_db_open ();
}

static void
test_canonicalization (InfoTestFixture *fixture, gconstpointer user_data)
{
  UnityWebappsApplicationInfo *info;
  gchar *canonical_name, *canonical_domain, *canonical_full_name;
  
  info = fixture->application_info;
  
  canonical_name = unity_webapps_application_info_get_canonical_name (info);
  canonical_domain = unity_webapps_application_info_get_canonical_domain (info);
  canonical_full_name = unity_webapps_application_info_get_canonical_full_name (info);
  
  g_assert (g_strcmp0 ("Test", canonical_name) == 0);
  g_assert (g_strcmp0 ("testts", canonical_domain) == 0);
  g_assert (g_strcmp0 ("Testtestts", canonical_full_name) == 0);
  
  g_free (canonical_name);
  g_free (canonical_domain);
  g_free (canonical_full_name);
}

static void
test_ensure_desktop_file (InfoTestFixture *fixture, gconstpointer user_data)
{
  UnityWebappsApplicationInfo *info;
  GError *error;
  
  info = (fixture)->application_info;
  
  error = NULL;
  
  unity_webapps_application_info_ensure_desktop_file (info, &error);
  
  g_assert (error == NULL);
  
  g_assert (g_file_test ("test-output-files/Testtestts.desktop", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
}

static void
test_write_name_with_spaces_desktop_file (InfoTestFixture *fixture, gconstpointer user_data)
{
  UnityWebappsApplicationInfo *info;
  GError *error;
  
  info = (fixture)->application_info;
  
  error = NULL;
  
  unity_webapps_application_info_ensure_desktop_file (info, &error);
  
  g_assert (error == NULL);
  
  g_assert (g_file_test ("test-output-files/TestSpacetestts.desktop", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
}

static void
test_set_homepage (InfoTestFixture *fixture, gconstpointer user_data)
{
  UnityWebappsApplicationInfo *info;
  GError *error;
  
  info = (fixture)->application_info;
  
  error = NULL;
  
  unity_webapps_application_info_ensure_desktop_file (info, &error);
  
  g_assert (error == NULL);
  
  g_assert (g_file_test ("test-output-files/Testtestts.desktop", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
  
  unity_webapps_application_info_set_homepage (info, "http://www.google.com");
}

static void
test_update_homepage (InfoTestFixture *fixture, gconstpointer user_data)
{
  UnityWebappsApplicationInfo *info;
  GError *error;
  
  info = (fixture)->application_info;
  
  error = NULL;
  
  unity_webapps_application_info_ensure_desktop_file (info, &error);
  
  g_assert (error == NULL);
  
  g_assert (g_file_test ("test-output-files/Testtestts.desktop", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
  
  unity_webapps_application_info_set_homepage (info, "http://www.google.com");
  unity_webapps_application_info_set_homepage (info, "http://www.foo.com");
}

static void
test_save_icon (InfoTestFixture *fixture, gconstpointer user_data)
{
  UnityWebappsApplicationInfo *info;
  GError *error;
  
  info = (fixture)->application_info;

  error = NULL;
  
  unity_webapps_application_info_ensure_desktop_file (info, &error);
  
  g_assert (error == NULL);
  
  unity_webapps_application_info_save_icon_file (info);
}

static void
test_add_icon (InfoTestFixture *fixture, gconstpointer user_data)
{
  UnityWebappsApplicationInfo *info;
  
  info = (fixture)->application_info;
  
  unity_webapps_application_info_add_icon_at_size (info, ICON_URL, 32);
  unity_webapps_application_info_add_icon_at_size (info, "icon://Test-themed-application-icons", 32);
  
  g_assert (g_file_test ("test-output-files/apps/32/Test-test.ts.png", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
}

static void
test_add_icon_fail (InfoTestFixture *fixture, gconstpointer user_data)
{
  UnityWebappsApplicationInfo *info;
  
  info = (fixture)->application_info;
  
  unity_webapps_application_info_add_icon_at_size (info, ICON_URL, 32);
  unity_webapps_application_info_add_icon_at_size (info, "icon://Test-themed-application-icons", 32);
}

static void
test_add_icon_remove_resource_dir (InfoTestFixture *fixture, gconstpointer user_data)
{
  UnityWebappsApplicationInfo *info;
  
  info = (fixture)->application_info;
  
  unity_webapps_application_info_add_icon_at_size (info, ICON_URL, 32);
  system("rm -r test-output-files");
  unity_webapps_application_info_add_icon_at_size (info, "icon://Test-themed-application-icons", 32);
  create_test_output_files_dir (TRUE);
}

int 
main (int argc, char **argv)
{
  gtk_init (&argc, &argv);
  g_test_init (&argc, &argv, NULL);

  setup_unity_webapps_environment();
  
  g_test_add("/Info/Canonicalization", InfoTestFixture, NULL,
	     setup_fixture_testts, test_canonicalization, teardown_fixture);
  g_test_add("/Info/WriteDesktopFile", InfoTestFixture, NULL,
	     setup_fixture_testts, test_ensure_desktop_file, teardown_fixture);
  g_test_add("/Info/WriteNameWithSpacesDesktopFile", InfoTestFixture, NULL,
       setup_fixture_testts_space_in_name, test_write_name_with_spaces_desktop_file, teardown_fixture);
  g_test_add("/Info/SetHomepage", InfoTestFixture, NULL,
	     setup_fixture_testts, test_set_homepage, teardown_fixture);
  g_test_add("/Info/UpdateHomepage", InfoTestFixture, NULL,
	     setup_fixture_testts, test_update_homepage, teardown_fixture);
  g_test_add("/Icons/SaveIcon", InfoTestFixture, NULL,
	     setup_fixture_testts, test_save_icon, teardown_fixture);
  g_test_add("/Icons/InvalidDataIcon", InfoTestFixture, NULL,
	     setup_fixture_testts_invalid_data_icon, test_save_icon, teardown_fixture);
  g_test_add("/Icons/InvalidDataIconMime", InfoTestFixture, NULL,
	     setup_fixture_testts_invalid_data_icon_mime, test_save_icon, teardown_fixture);
  g_test_add("/Icons/AddSizedIcon", InfoTestFixture, NULL,
	     setup_fixture_testts, test_add_icon, teardown_fixture);
  g_test_add("/Icons/AddSizedIconRemoveDir", InfoTestFixture, NULL,
	     setup_fixture_testts, test_add_icon_remove_resource_dir, teardown_fixture);
  g_test_add("/Icons/AddSizedIconFail", InfoTestFixture, NULL,
	     setup_fixture_testts_write_failure, test_add_icon_fail, teardown_fixture);
  g_test_add("/Icons/ThemedIcon", InfoTestFixture, NULL,
	     setup_fixture_testts_themed_icon, test_save_icon, teardown_fixture);

  system("rm -rf test-output-files/*");
  create_test_output_files_dir (FALSE);

  return g_test_run ();
}
