#include "clar_libgit2.h"

void test_core_integer__multiply_int64_no_overflow(void)
{
#if !defined(git__multiply_int64_overflow)
	int64_t result = 0;
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x1ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x1ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x2ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x2ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x7ffffffffffffffll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x7ffffffffffffffll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x800000000000000ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x800000000000000ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x7fffffffffffffffll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x7fffffffffffffffll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x8000000000000000ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x1ll));
	cl_assert_equal_i(result, 0x1ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x1ll));
	cl_assert_equal_i(result, -0x1ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x2ll));
	cl_assert_equal_i(result, 0x2ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x2ll));
	cl_assert_equal_i(result, -0x2ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x7ffffffffffffffll));
	cl_assert_equal_i(result, 0x7ffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x7ffffffffffffffll));
	cl_assert_equal_i(result, -0x7ffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x800000000000000ll));
	cl_assert_equal_i(result, 0x800000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x800000000000000ll));
	cl_assert_equal_i(result, -0x800000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x7fffffffffffffffll));
	cl_assert_equal_i(result, 0x7fffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x7fffffffffffffffll));
	cl_assert_equal_i(result, -0x7fffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x1ll));
	cl_assert_equal_i(result, -0x1ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x1ll));
	cl_assert_equal_i(result, 0x1ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x2ll));
	cl_assert_equal_i(result, -0x2ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x2ll));
	cl_assert_equal_i(result, 0x2ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x7ffffffffffffffll));
	cl_assert_equal_i(result, -0x7ffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x7ffffffffffffffll));
	cl_assert_equal_i(result, 0x7ffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x800000000000000ll));
	cl_assert_equal_i(result, -0x800000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x800000000000000ll));
	cl_assert_equal_i(result, 0x800000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x7fffffffffffffffll));
	cl_assert_equal_i(result, -0x7fffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x7fffffffffffffffll));
	cl_assert_equal_i(result, 0x7fffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x1ll));
	cl_assert_equal_i(result, 0x2ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x1ll));
	cl_assert_equal_i(result, -0x2ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x2ll));
	cl_assert_equal_i(result, 0x4ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x2ll));
	cl_assert_equal_i(result, -0x4ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x7ffffffffffffffll));
	cl_assert_equal_i(result, 0xffffffffffffffell);
	cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x7ffffffffffffffll));
	cl_assert_equal_i(result, -0xffffffffffffffell);
	cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x800000000000000ll));
	cl_assert_equal_i(result, 0x1000000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x800000000000000ll));
	cl_assert_equal_i(result, -0x1000000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x1ll));
	cl_assert_equal_i(result, -0x2ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x1ll));
	cl_assert_equal_i(result, 0x2ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x2ll));
	cl_assert_equal_i(result, -0x4ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x2ll));
	cl_assert_equal_i(result, 0x4ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x7ffffffffffffffll));
	cl_assert_equal_i(result, -0xffffffffffffffell);
	cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x7ffffffffffffffll));
	cl_assert_equal_i(result, 0xffffffffffffffell);
	cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x800000000000000ll));
	cl_assert_equal_i(result, -0x1000000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x800000000000000ll));
	cl_assert_equal_i(result, 0x1000000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x4000000000000000ll));
	cl_assert_equal_i(result, -0x8000000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x1ll));
	cl_assert_equal_i(result, 0x7ffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x1ll));
	cl_assert_equal_i(result, -0x7ffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x2ll));
	cl_assert_equal_i(result, 0xffffffffffffffell);
	cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x2ll));
	cl_assert_equal_i(result, -0xffffffffffffffell);
	cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x1ll));
	cl_assert_equal_i(result, -0x7ffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x1ll));
	cl_assert_equal_i(result, 0x7ffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x2ll));
	cl_assert_equal_i(result, -0xffffffffffffffell);
	cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x2ll));
	cl_assert_equal_i(result, 0xffffffffffffffell);
	cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x1ll));
	cl_assert_equal_i(result, 0x800000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x1ll));
	cl_assert_equal_i(result, -0x800000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x2ll));
	cl_assert_equal_i(result, 0x1000000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x2ll));
	cl_assert_equal_i(result, -0x1000000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x1ll));
	cl_assert_equal_i(result, -0x800000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x1ll));
	cl_assert_equal_i(result, 0x800000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x2ll));
	cl_assert_equal_i(result, -0x1000000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x2ll));
	cl_assert_equal_i(result, 0x1000000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x1ll));
	cl_assert_equal_i(result, 0x7fffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x1ll));
	cl_assert_equal_i(result, -0x7fffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x4000000000000000ll, 0x2ll));
	cl_assert_equal_i(result, -0x8000000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x1ll));
	cl_assert_equal_i(result, -0x7fffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x1ll));
	cl_assert_equal_i(result, 0x7fffffffffffffffll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x0ll));
	cl_assert_equal_i(result, 0x0ll);
#endif
}

void test_core_integer__multiply_int64_overflow(void)
{
#if !defined(git__multiply_int64_overflow)
	int64_t result = 0;
	cl_assert(git__multiply_int64_overflow(&result, 0x2ll, 0x4000000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x2ll, 0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x2ll, -0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x2ll, -0x8000000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x2ll, 0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x2ll, -0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x2ll, -0x8000000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x8000000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x8000000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x8000000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x8000000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x4000000000000000ll, 0x2ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x2ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x2ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x8000000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x2ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x2ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x8000000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x2ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x2ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x7ffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x800000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x7fffffffffffffffll));
	cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x8000000000000000ll));
#endif
}

void test_core_integer__multiply_int64_edge_cases(void)
{
#if !defined(git__multiply_int64_overflow)
	int64_t result = 0;
	cl_assert(!git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x1ll));
	cl_assert_equal_i(result, -0x8000000000000000ll);
	cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x8000000000000000ll));
	cl_assert_equal_i(result, -0x8000000000000000ll);
	cl_assert(git__multiply_int64_overflow(&result, 0x1ll, -0x8000000000000000ll));
	cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x1ll));
#endif
}
