/*
 * Seagull: A SQLite helper library
 * Copyright (C) Seagull Developers
 *
 * Seagull is the legal property of its developers, whose names are too
 * numerous to list here. Please refer to the AUTHORS file distributed with
 * this source distribution
 *
 * This program 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 2.1 of the License, or (at your
 * option) any later version.
 *
 * This program 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 library; if not, see <https://www.gnu.org/licenses/>.
 */

#include <glib.h>

#include <sqlite3.h>

#include <seagull.h>

/******************************************************************************
 * Main
 *****************************************************************************/
static void
test_seagull_transaction_begin_commit(void) {
	SeagullSqlite3 *db = NULL;
	GError *error = NULL;
	int rc = SQLITE_OK;
	gboolean result = FALSE;

	rc = sqlite3_open(":memory:", &db);
	g_assert_nonnull(db);
	g_assert_cmpint(rc, ==, SQLITE_OK);

	result = seagull_transaction_begin(db, &error);
	g_assert_no_error(error);
	g_assert_true(result);

	result = seagull_transaction_commit(db, &error);
	g_assert_no_error(error);
	g_assert_true(result);

	rc = sqlite3_close(db);
	g_assert_cmpint(rc, ==, SQLITE_OK);
}

static void
test_seagull_transaction_begin_rollback(void) {
	SeagullSqlite3 *db = NULL;
	GError *error = NULL;
	int rc = SQLITE_OK;
	gboolean result = FALSE;

	rc = sqlite3_open(":memory:", &db);
	g_assert_nonnull(db);
	g_assert_cmpint(rc, ==, SQLITE_OK);

	result = seagull_transaction_begin(db, &error);
	g_assert_no_error(error);
	g_assert_true(result);

	result = seagull_transaction_rollback(db, &error);
	g_assert_no_error(error);
	g_assert_true(result);

	rc = sqlite3_close(db);
	g_assert_cmpint(rc, ==, SQLITE_OK);
}

static void
test_seagull_transaction_begin_begin(void) {
	SeagullSqlite3 *db = NULL;
	GError *error = NULL;
	int rc = SQLITE_OK;
	gboolean result = FALSE;

	rc = sqlite3_open(":memory:", &db);
	g_assert_nonnull(db);
	g_assert_cmpint(rc, ==, SQLITE_OK);

	result = seagull_transaction_begin(db, &error);
	g_assert_no_error(error);
	g_assert_true(result);

	result = seagull_transaction_begin(db, &error);
	g_assert_error(error,
	               SEAGULL_TRANSACTION_ERROR,
	               SEAGULL_TRANSACTION_ERROR_BEGIN_FAILED);
	g_clear_error(&error);
	g_assert_false(result);

	rc = sqlite3_close(db);
	g_assert_cmpint(rc, ==, SQLITE_OK);
}

static void
test_seagull_transaction_commit_without_begin(void) {
	SeagullSqlite3 *db = NULL;
	GError *error = NULL;
	int rc = SQLITE_OK;
	gboolean result = FALSE;

	rc = sqlite3_open(":memory:", &db);
	g_assert_nonnull(db);
	g_assert_cmpint(rc, ==, SQLITE_OK);

	result = seagull_transaction_commit(db, &error);
	g_assert_error(error,
	               SEAGULL_TRANSACTION_ERROR,
	               SEAGULL_TRANSACTION_ERROR_COMMIT_FAILED);
	g_clear_error(&error);
	g_assert_false(result);

	rc = sqlite3_close(db);
	g_assert_cmpint(rc, ==, SQLITE_OK);
}

static void
test_seagull_transaction_rollback_without_begin(void) {
	SeagullSqlite3 *db = NULL;
	GError *error = NULL;
	int rc = SQLITE_OK;
	gboolean result = FALSE;

	rc = sqlite3_open(":memory:", &db);
	g_assert_nonnull(db);
	g_assert_cmpint(rc, ==, SQLITE_OK);

	result = seagull_transaction_rollback(db, &error);
	g_assert_error(error,
	               SEAGULL_TRANSACTION_ERROR,
	               SEAGULL_TRANSACTION_ERROR_ROLLBACK_FAILED);
	g_clear_error(&error);
	g_assert_false(result);

	rc = sqlite3_close(db);
	g_assert_cmpint(rc, ==, SQLITE_OK);
}

/******************************************************************************
 * Main
 *****************************************************************************/
int
main(int argc, char *argv[]) {
	g_test_init(&argc, &argv, NULL);

	g_test_add_func("/transaction/begin-commit",
	                test_seagull_transaction_begin_commit);
	g_test_add_func("/transaction/begin-rollback",
	                test_seagull_transaction_begin_rollback);
	g_test_add_func("/transaction/begin-begin",
	                test_seagull_transaction_begin_begin);

	g_test_add_func("/transaction/commit-without-begin",
	                test_seagull_transaction_commit_without_begin);
	g_test_add_func("/transaction/rollback-without-begin",
	                test_seagull_transaction_rollback_without_begin);

	return g_test_run();
}
