using GLib;

public sealed class McuAssert : Object {
	public static void ints_equal(int actual, int expected) {
		if (actual != expected) {
			stderr.printf("\n====================\n");
			stderr.printf("FAILED: int not equal to int.\n");
			stderr.printf("  Expected: 0x%08X\n", (uint) expected);
			stderr.printf("  Actual: 0x%08X\n", (uint) actual);
			stderr.printf("====================\n");
		}
		assert(actual == expected);
	}

	public static void int_and_uint_equal(int actual, uint expected) {
		if ((uint) actual != expected) {
			stderr.printf("\n====================\n");
			stderr.printf("FAILED: int not equal to uint.\n");
			stderr.printf("  Expected: 0x%08X\n", expected);
			stderr.printf("  Actual: 0x%08X\n", (uint) actual);
			stderr.printf("====================\n");
		}
		assert((uint) actual == expected);
	}

	public static void uints_equal(uint actual, uint expected) {
		if (actual != expected) {
			stderr.printf("\n====================\n");
			stderr.printf("FAILED: uint not equal to uint.\n");
			stderr.printf("  Expected: 0x%08X\n", expected);
			stderr.printf("  Actual: 0x%08X\n", actual);
			stderr.printf("====================\n");
		}
		assert(actual == expected);
	}

	public static void doubles_equal(double actual, double expected, double accuracy = 0.001) {
		if (Math.fabs(expected - actual) > accuracy) {
			stderr.printf("\n====================\n");
			stderr.printf("FAILED: double comparison outside accuracy bounds.\n");
			stderr.printf("  Expected: %f (± %f)\n", expected, accuracy);
			stderr.printf("  Actual: %f\n", actual);
			stderr.printf("====================\n");
		}
		assert(Math.fabs(expected - actual) <= accuracy);
	}

	public static void double_greater_than_double(double actual, double expected, bool equal = false) {
		if (equal ? actual < expected : actual <= expected) {
			stderr.printf("\n====================\n");
			stderr.printf("FAILED: double not greater%s.\n", equal ? " or equal" : "");
			stderr.printf("  Expected: %s %f\n", equal ? ">=" : ">", expected);
			stderr.printf("  Actual: %f\n", actual);
			stderr.printf("====================\n");
		}
		assert(equal ? actual >= expected : actual > expected);
	}

	public static void double_less_than_double(double actual, double expected, bool equal = false) {
		if (equal ? actual > expected : actual >= expected) {
			stderr.printf("\n====================\n");
			stderr.printf("FAILED: double not less%s.\n", equal ? " or equal" : "");
			stderr.printf("  Expected: %s %f\n", equal ? "<=" : "<", expected);
			stderr.printf("  Actual: %f\n", actual);
			stderr.printf("====================\n");
		}
		assert(equal ? actual <= expected : actual < expected);
	}

	public static void true(bool actual) {
		if (!actual) {
			stderr.printf("\n====================\n");
			stderr.printf("FAILED: bool not true.\n");
			stderr.printf("  Expected: true\n");
			stderr.printf("  Actual: false\n");
			stderr.printf("====================\n");
		}
		assert_true(actual);
	}

	public static void false(bool actual) {
		if (actual) {
			stderr.printf("\n====================\n");
			stderr.printf("FAILED: bool not false.\n");
			stderr.printf("  Expected: false\n");
			stderr.printf("  Actual: true\n");
			stderr.printf("====================\n");
		}
		assert_false(actual);
	}
}
