#include "src/bookmarks/kz-bookmark-file.h"

#include <gcutter.h>
#include "kz-test-utils.h"

void test_new (void);
void test_create_new (void);
void test_file_type (void);
void test_document_title (void);
void test_location (void);
void test_interval (void);
void test_xmlrpc_address (void);
void test_xmlrpc_user (void);
void test_xmlrpc_pass (void);
void test_load (void);
void test_save (void);
void data_load_start (void);
void test_load_start (gconstpointer data);

static KzBookmarkFile *file;
static KzBookmark *expected;
static gchar *file_path;

static gint n_load_start_received;
static gint n_load_completed_received;
static gint n_load_error_received;
static gchar *error_message;
static const gchar temporary_bookmark_file[] = "tmp_bookmark.xml";

void
setup (void)
{
    file =  NULL;
    expected = NULL;

    n_load_start_received = 0;
    n_load_completed_received = 0;
    n_load_error_received = 0;

    error_message = NULL;

    file_path = g_build_filename(kz_test_get_base_dir(),
                                 "fixtures", "bookmarks.xml",
                                 NULL);
}

void
teardown (void)
{
    if (file)
        g_object_unref(file);
    if (expected)
        g_object_unref(expected);
    g_free(file_path);
    g_free(error_message);

    cut_remove_path(temporary_bookmark_file, NULL);
}

void
test_new (void)
{
    file = kz_bookmark_file_new(file_path, "Bookmark file", "XBEL");
    cut_assert(file);
    cut_assert_true(KZ_IS_BOOKMARK_FILE(file));
    cut_assert_true(KZ_IS_BOOKMARK_FOLDER(file));
}

void
test_create_new (void)
{
    file = kz_bookmark_file_create_new(temporary_bookmark_file, "Temporary", "XBEL");

    cut_assert_true(KZ_IS_BOOKMARK_FILE(file));
    cut_assert_true(KZ_IS_BOOKMARK_FOLDER(file));
    cut_assert_false(kz_bookmark_folder_has_children(KZ_BOOKMARK_FOLDER(file)));
}

void
test_file_type (void)
{
    cut_trace(test_new());

    cut_assert_equal_string("XBEL", kz_bookmark_file_get_file_type(file));
}

void
test_document_title (void)
{
    cut_trace(test_new());
    cut_assert_null(kz_bookmark_file_get_document_title(file));
    kz_bookmark_file_set_document_title(file, "12345");
    cut_assert_equal_string("12345", kz_bookmark_file_get_document_title(file));
}

void
test_location (void)
{
    cut_trace(test_new());

    cut_assert_equal_string(file_path, kz_bookmark_file_get_location(file));

    kz_bookmark_file_set_location(file, "Where am I?");
    cut_assert_equal_string("Where am I?", kz_bookmark_file_get_location(file));
}

void
test_interval (void)
{
    cut_trace(test_new());

    kz_bookmark_file_set_interval(file, 9999);
    cut_assert_equal_uint(9999, kz_bookmark_file_get_interval(file));

    kz_bookmark_file_set_interval(file, G_MAXUINT);
    cut_assert_equal_uint(G_MAXUINT, kz_bookmark_file_get_interval(file));
}

void
test_xmlrpc_address (void)
{
    cut_trace(test_new());

    kz_bookmark_file_set_xmlrpc(file, "http://example.com/");
    cut_assert_equal_string("http://example.com/",  kz_bookmark_file_get_xmlrpc(file));

    kz_bookmark_file_set_xmlrpc(file, "http://example.com/1/");
    cut_assert_equal_string("http://example.com/1/",  kz_bookmark_file_get_xmlrpc(file));
}

void
test_xmlrpc_user (void)
{
    cut_trace(test_new());

    kz_bookmark_file_set_xmlrpc_user(file, "user1");
    cut_assert_equal_string("user1",  kz_bookmark_file_get_xmlrpc_user(file));

    kz_bookmark_file_set_xmlrpc_user(file, "user2");
    cut_assert_equal_string("user2",  kz_bookmark_file_get_xmlrpc_user(file));
}

void
test_xmlrpc_pass (void)
{
    cut_trace(test_new());

    kz_bookmark_file_set_xmlrpc_pass(file, "pass1");
    cut_assert_equal_string("pass1",  kz_bookmark_file_get_xmlrpc_pass(file));

    kz_bookmark_file_set_xmlrpc_pass(file, "pass2");
    cut_assert_equal_string("pass2",  kz_bookmark_file_get_xmlrpc_pass(file));
}

void
test_load (void)
{
    cut_trace(test_new());

    kz_bookmark_file_load(file);

    expected = KZ_BOOKMARK(g_object_new(KZ_TYPE_BOOKMARK_FILE,
                                        "location", file_path,
                                        "title", "Bookmark file",
                                        "file-type", "XBEL",
                                        NULL));
    kz_bookmark_folder_append(KZ_BOOKMARK_FOLDER(expected),
                              kz_bookmark_new_with_attrs("Kazehakase",
                                                         "http://kazehakase.sourceforge.jp/",
                                                         NULL));
    kz_assert_equal_bookmark(expected, KZ_BOOKMARK(file));
}

void
test_save (void)
{
    cut_trace(test_create_new());

    kz_bookmark_file_save(file);
    cut_assert_file_exist(temporary_bookmark_file);
}

static gboolean
cb_check_emitted (gpointer data)
{
    gboolean *emitted = data;

    *emitted = TRUE;
    return FALSE;
}

static void
wait_signal (gint *n_signals)
{
    gboolean timeout_emitted = FALSE;
    guint timeout_id;

    timeout_id = g_timeout_add_seconds(1, cb_check_emitted, &timeout_emitted);
    while (!timeout_emitted && *n_signals == 0)
        g_main_context_iteration(NULL, TRUE);

    g_source_remove(timeout_id);

    //cut_assert_false(timeout_emitted, "timeout");
}

static void 
cb_load_start (KzBookmarkFile *bookmark_file, gpointer data)
{
    n_load_start_received++;
}

static void 
cb_load_completed (KzBookmarkFile *bookmark_file, gpointer data)
{
    n_load_completed_received++;
}

static void 
cb_load_error (KzBookmarkFile *bookmark_file, const gchar *message, gpointer data)
{
    n_load_error_received++;
    error_message = g_strdup(message);
}

static void
setup_signals (void)
{
    g_signal_connect(file, "load-start",
                     G_CALLBACK(cb_load_start), NULL);
    g_signal_connect(file, "load-completed",
                     G_CALLBACK(cb_load_completed), NULL);
    g_signal_connect(file, "error",
                     G_CALLBACK(cb_load_error), NULL);
}

void
data_load_start (void)
{
    cut_add_data("local bookmark",
                 g_build_filename(kz_test_get_base_dir(),
                                 "fixtures", "bookmarks.xml",
                                 NULL),
                 g_free,
                 "remote bookmark",
                 "http://svn.sourceforge.jp/view/kazehakase/trunk/test/fixtures/bookmarkbar.xml?view=co&root=kazehakase",
                 NULL);
}

void
test_load_start (gconstpointer data)
{
    const gchar *uri = data;

    file = kz_bookmark_file_new(uri, "Bookmark file", "XBEL");
    cut_assert(file);

    setup_signals();
    cut_assert_true(kz_bookmark_file_load_start(file));

    wait_signal(&n_load_start_received);
    cut_assert_equal_int(1, n_load_start_received);
    wait_signal(&n_load_completed_received);
    cut_assert_equal_string(NULL, error_message);
    cut_assert_equal_int(0, n_load_error_received);
    cut_assert_equal_int(1, n_load_completed_received);

    expected = KZ_BOOKMARK(g_object_new(KZ_TYPE_BOOKMARK_FILE,
                                        "location", uri,
                                        "title", "Bookmark file",
                                        "file-type", "XBEL",
                                        NULL));
    kz_bookmark_folder_append(KZ_BOOKMARK_FOLDER(expected),
                              kz_bookmark_new_with_attrs("Kazehakase",
                                                         "http://kazehakase.sourceforge.jp/",
                                                         NULL));
    kz_assert_equal_bookmark(expected, KZ_BOOKMARK(file));
}

/*
vi:ts=4:nowrap:ai:expandtab:sw=4
*/
