void
__test_seeks(Journald *journald)
{
  gint result = journald_seek_head(journald);
  assert_gint(result, 0, ASSERTION_ERROR("Can't seek in empty journald mock"));
  result = journald_next(journald);
  assert_gint(result, 0, ASSERTION_ERROR("Bad next step result"));

  MockEntry *entry = mock_entry_new("test_data1");
  mock_entry_add_data(entry, "MESSAGE=test message");
  mock_entry_add_data(entry, "KEY=VALUE");
  mock_entry_add_data(entry, "HOST=testhost");

  journald_mock_add_entry(journald, entry);

  entry = mock_entry_new("test_data2");
  mock_entry_add_data(entry, "MESSAGE=test message2");
  mock_entry_add_data(entry, "KEY=VALUE2");
  mock_entry_add_data(entry, "HOST=testhost2");

  journald_mock_add_entry(journald, entry);

  result = journald_seek_head(journald);
  assert_gint(result, 0, ASSERTION_ERROR("Can't seek in journald mock"));
  result = journald_next(journald);
  assert_gint(result, 1, ASSERTION_ERROR("Bad next step result"));
}
void
_test_timezone_init(TestCase *self, TestSource *src, Journald *journal, JournalReader *reader, JournalReaderOptions *options)
{
  MockEntry *entry = __create_real_entry(journal, "time_zone_test");
  options->recv_time_zone = g_strdup("+09:00");
  journald_mock_add_entry(journal, entry);
}
void
add_mock_entries(gpointer user_data)
{
  Journald *journald = user_data;
  MockEntry *entry = mock_entry_new("test_data3");
  mock_entry_add_data(entry, "MESSAGE=test message3");
  mock_entry_add_data(entry, "KEY=VALUE3");
  mock_entry_add_data(entry, "HOST=testhost3");
  journald_mock_add_entry(journald, entry);

  entry = mock_entry_new("test_data4");
  mock_entry_add_data(entry, "MESSAGE=test message4");
  mock_entry_add_data(entry, "KEY=VALUE4");
  mock_entry_add_data(entry, "HOST=testhost4");
  journald_mock_add_entry(journald, entry);
}
void
_test_field_size_init(TestCase *self, TestSource *src, Journald *journal, JournalReader *reader, JournalReaderOptions *options)
{
  MockEntry *entry = __create_real_entry(journal, "field_size_test");
  options->max_field_size = GPOINTER_TO_INT(self->user_data);
  journald_mock_add_entry(journal, entry);
}
void
test_journald_helper()
{
  Journald *journald = journald_mock_new();
  journald_open(journald, 0);

  MockEntry *entry = mock_entry_new("test_data1");
  mock_entry_add_data(entry, "MESSAGE=test message");
  mock_entry_add_data(entry, "KEY=VALUE");
  mock_entry_add_data(entry, "HOST=testhost");

  journald_mock_add_entry(journald, entry);
  journald_seek_head(journald);
  journald_next(journald);

  GHashTable *result = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
  journald_foreach_data(journald, __helper_test, result);

  gchar *message = g_hash_table_lookup(result, "MESSAGE");
  gchar *key = g_hash_table_lookup(result, "KEY");
  gchar *host = g_hash_table_lookup(result, "HOST");

  assert_string(message, "test message", ASSERTION_ERROR("Bad item"));
  assert_string(key, "VALUE", ASSERTION_ERROR("Bad item"));
  assert_string(host, "testhost", ASSERTION_ERROR("Bad item"));

  journald_close(journald);
  journald_free(journald);
  g_hash_table_unref(result);
}
Test(systemd_journal, test_journald_helper)
{
  const gchar *persist_file = "test_systemd_journal2.persist";

  _init_cfg_with_persist_file(persist_file);
  Journald *journald = journald_mock_new();
  journald_open(journald, 0);

  MockEntry *entry = mock_entry_new("test_data1");
  mock_entry_add_data(entry, "MESSAGE=test message");
  mock_entry_add_data(entry, "KEY=VALUE");
  mock_entry_add_data(entry, "HOST=testhost");

  journald_mock_add_entry(journald, entry);
  journald_seek_head(journald);
  journald_next(journald);

  GHashTable *result = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
  journald_foreach_data(journald, __helper_test, result);

  gchar *message = g_hash_table_lookup(result, "MESSAGE");
  gchar *key = g_hash_table_lookup(result, "KEY");
  gchar *host = g_hash_table_lookup(result, "HOST");

  cr_assert_str_eq(message, "test message", "%s", "Bad item");
  cr_assert_str_eq(key, "VALUE", "%s", "Bad item");
  cr_assert_str_eq(host, "testhost", "%s", "Bad item");

  journald_close(journald);
  journald_free(journald);
  g_hash_table_unref(result);

  _deinit_cfg(persist_file);
}
void
_test_default_working_init(TestCase *self, TestSource *src, Journald *journal, JournalReader *reader, JournalReaderOptions *options)
{
  MockEntry *entry = __create_dummy_entry(journal, "default_test");
  journald_mock_add_entry(journal, entry);
  configuration->recv_time_zone = g_strdup("+06:00");
  self->user_data = options;
}
void
_test_prefix_init(TestCase *self, TestSource *src, Journald *journal, JournalReader *reader, JournalReaderOptions *options)
{
  MockEntry *entry = __create_real_entry(journal, "prefix_test");

  options->prefix = g_strdup((gchar *)self->user_data);

  journald_mock_add_entry(journal, entry);
}
void
_test_default_facility_init(TestCase *self, TestSource *src, Journald *journal, JournalReader *reader, JournalReaderOptions *options)
{
  MockEntry *entry = __create_dummy_entry(journal, "test default facility");
  gint facility = GPOINTER_TO_INT(self->user_data);
  if(options->default_pri == 0xFFFF)
    options->default_pri = LOG_NOTICE;
  options->default_pri = (options->default_pri & 7) | facility;
  journald_mock_add_entry(journal, entry);
}
void
_test_default_level_init(TestCase *self, TestSource *src, Journald *journal, JournalReader *reader, JournalReaderOptions *options)
{
  MockEntry *entry = __create_dummy_entry(journal, "test default level");
  gint level = GPOINTER_TO_INT(self->user_data);
  if (options->default_pri == 0xFFFF)
    options->default_pri = LOG_USER;
  options->default_pri = (options->default_pri & ~7) | level;

  journald_mock_add_entry(journal, entry);
}
void
_test_program_field_init(TestCase *self, TestSource *src, Journald *journal, JournalReader *reader,
                         JournalReaderOptions *options)
{
  MockEntry *entry = mock_entry_new("test _COMM first win");
  mock_entry_add_data(entry, "_COMM=comm_program");
  mock_entry_add_data(entry, "SYSLOG_IDENTIFIER=syslog_program");
  journald_mock_add_entry(journal, entry);

  entry = mock_entry_new("test _COMM second win");
  mock_entry_add_data(entry, "SYSLOG_IDENTIFIER=syslog_program");
  mock_entry_add_data(entry, "_COMM=comm_program");
  journald_mock_add_entry(journal, entry);

  entry = mock_entry_new("no SYSLOG_IDENTIFIER");
  mock_entry_add_data(entry, "_COMM=comm_program");
  journald_mock_add_entry(journal, entry);

  self->user_data = journal;
}