/*
 * Copyright (C) 2025 The Phosh Developers
 *
 * SPDX-License-Identifier: GPL-3.0+
 *
 * Author: Evangelos Ribeiro Tzaras <devrtz@fortysixandtwo.eu>
 */

#include "lcb-util.h"
#include "lcb-util-priv.h"
#include "lcb-message-priv.h"

static void
test_simple_store_retrieve (void)
{
  g_autoptr (GError) error = NULL;
  g_autofree char *db_path = g_test_build_filename (G_TEST_BUILT, "messages.gvdb", NULL);
  GListStore *messages_out;
  GListModel *messages_in;
  LcbMessage *msg1, *msg2;
  LcbMessage *read1, *read2;
  gboolean ok;

  msg1 = lcb_message_new ("This is a test",
                          4391, 12, 0, 42, LCB_SEVERITY_LEVEL_TEST,
                          "Test alert", NULL);
  msg2 = lcb_message_new ("This is another test",
                          4391, 125, 1, 31337, LCB_SEVERITY_LEVEL_PRESIDENTIAL,
                          "Presidential alert", "00101");

  messages_out = g_list_store_new (LCB_TYPE_MESSAGE);
  g_list_store_append (messages_out, msg1);
  g_list_store_append (messages_out, msg2);

  ok = lcb_util_save_messages_to_file (G_LIST_MODEL (messages_out), db_path, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  g_assert_true (g_file_test (db_path, G_FILE_TEST_EXISTS && G_FILE_TEST_IS_REGULAR));

  messages_in = lcb_util_load_messages_from_file (db_path, &error);
  g_assert_no_error (error);
  g_assert_nonnull (messages_in);
  g_assert_cmpuint (g_list_model_get_n_items (messages_in), ==, 2);

  read1 = g_list_model_get_item (messages_in, 0);

  g_assert_cmpstr (lcb_message_get_text (msg1), ==, lcb_message_get_text (read1));
  g_assert_cmpuint (lcb_message_get_channel (msg1), ==, lcb_message_get_channel (read1));
  g_assert_cmpuint (lcb_message_get_msg_code (msg1), ==, lcb_message_get_msg_code (read1));
  g_assert_cmpuint (lcb_message_get_update (msg1), ==, lcb_message_get_update (read1));
  g_assert_cmpint (lcb_message_get_timestamp (msg1), ==, lcb_message_get_timestamp (read1));
  g_assert_cmpint (lcb_message_get_severity (msg1), ==, lcb_message_get_severity (read1));
  g_assert_cmpstr (lcb_message_get_severity_subject (msg1), ==, lcb_message_get_severity_subject (read1));
  g_assert_cmpstr (lcb_message_get_operator_code (msg1), ==, lcb_message_get_operator_code (read1));

  read2 = g_list_model_get_item (G_LIST_MODEL (messages_in), 1);

  g_assert_cmpstr (lcb_message_get_text (msg2), ==, lcb_message_get_text (read2));
  g_assert_cmpuint (lcb_message_get_channel (msg2), ==, lcb_message_get_channel (read2));
  g_assert_cmpuint (lcb_message_get_msg_code (msg2), ==, lcb_message_get_msg_code (read2));
  g_assert_cmpuint (lcb_message_get_update (msg2), ==, lcb_message_get_update (read2));
  g_assert_cmpint (lcb_message_get_timestamp (msg2), ==, lcb_message_get_timestamp (read2));
  g_assert_cmpint (lcb_message_get_severity (msg2), ==, lcb_message_get_severity (read2));
  g_assert_cmpstr (lcb_message_get_severity_subject (msg2), ==, lcb_message_get_severity_subject (read2));
  g_assert_cmpstr (lcb_message_get_operator_code (msg2), ==, lcb_message_get_operator_code (read2));

  g_assert_finalize_object (messages_in);
  g_assert_finalize_object (messages_out);

  g_assert_finalize_object (msg1);
  g_assert_finalize_object (read1);

  g_assert_finalize_object (msg2);
  g_assert_finalize_object (read2);
}


static void
test_null_bytes (void)
{
  g_autoptr (GError) error = NULL;
  g_autofree char *db_path = g_test_build_filename (G_TEST_BUILT, "messages-null.gvdb", NULL);
  GListModel *messages;
  GPtrArray *raw_messages;
  gboolean ok;

  raw_messages = lcb_util_load_raw_messages_from_bytes (NULL, &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
  g_assert_null (raw_messages);
  g_clear_error (&error);

  messages = lcb_util_load_messages_from_bytes (NULL, &error);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
  g_assert_null (messages);
  g_clear_error (&error);

  ok = lcb_util_save_messages_to_file (NULL, db_path, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  g_assert_true (g_file_test (db_path, G_FILE_TEST_EXISTS && G_FILE_TEST_IS_REGULAR));
}


static void
test_empty_messages (void)
{
  g_autoptr (GError) error = NULL;
  g_autofree char *db_path = g_test_build_filename (G_TEST_BUILT, "messages-empty.gvdb", NULL);
  GListModel *messages_out, *messages_in;
  GPtrArray *raw_messages;
  gboolean ok;

  messages_out = G_LIST_MODEL (g_list_store_new (LCB_TYPE_MESSAGE));

  ok = lcb_util_save_messages_to_file (messages_out, db_path, &error);
  g_assert_no_error (error);
  g_assert_true (ok);
  g_assert_true (g_file_test (db_path, G_FILE_TEST_EXISTS && G_FILE_TEST_IS_REGULAR));
  g_assert_finalize_object (messages_out);

  messages_in = lcb_util_load_messages_from_file (db_path, &error);
  g_assert_no_error (error);
  g_assert_nonnull (messages_in);
  g_assert_cmpuint (g_list_model_get_n_items (messages_in), ==, 0);
  g_assert_finalize_object (messages_in);

  raw_messages = lcb_util_load_raw_messages_from_file (db_path, &error);
  g_assert_no_error (error);
  g_assert_nonnull (raw_messages);
  g_assert_cmpuint (raw_messages->len, ==, 0);

  g_clear_pointer (&raw_messages, g_ptr_array_unref);
}
int
main (int argc, char *argv[])
{
  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/cbd/util/history/simple_store_retrieve", test_simple_store_retrieve);
  g_test_add_func ("/cbd/util/history/null", test_null_bytes);
  g_test_add_func ("/cbd/util/history/empty", test_empty_messages);

  return g_test_run ();
}
