package oving7.savingsaccount;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class SavingsAccountTest {

	private static final double epsilon = 0.001;

	private SavingsAccount savingsAccount;

	@BeforeEach
	public void setUp() {
		savingsAccount = new SavingsAccount(0.1);
	}

	@Test
	@DisplayName("Check that the balance is correct after deposit")
	public void testBalance() {
		savingsAccount.deposit(100.0);
		assertEquals(100.0, savingsAccount.getBalance(), epsilon,
				"The account balance was incorrect");
	}

	@Test
	@DisplayName("Test deposit and withdraw")
	public void testDepositAndWithdraw() {
		savingsAccount.deposit(100.0);
		savingsAccount.withdraw(40.0);
		assertEquals(60.0, savingsAccount.getBalance(), epsilon,
				"The account balance was incorrect");
	}

	@Test
	@DisplayName("Test deposit and withdraw with illegal input")
	public void testDepositAndWithdrawIllegalInput() {
		savingsAccount.deposit(10.0);

		assertThrows(IllegalArgumentException.class, () -> {
			savingsAccount.deposit(-100.0);
		}, "Negative deposit should have triggered an IllegalArgumentException!");

		assertEquals(10.0, savingsAccount.getBalance(), epsilon,
				"The account balance was incorrect");

		savingsAccount.deposit(10.0);

		assertThrows(IllegalArgumentException.class, () -> {
			savingsAccount.withdraw(-100.0);
		}, "Negative withdrawal should have triggered an IllegalArgumentException!");

		assertEquals(20.0, savingsAccount.getBalance(), epsilon,
				"The account balance was incorrect");

		savingsAccount.deposit(10.0);

		assertThrows(IllegalArgumentException.class, () -> {
			savingsAccount.withdraw(40.0);
		}, "Withdrawal of more than the balance should have triggered an IllegalArgumentException");

		assertEquals(30.0, savingsAccount.getBalance(), epsilon,
				"The account balance was incorrect");
	}

	@Test
	@DisplayName("Test that the interest is calculated correctly")
	public void endYearUpdate() {
		savingsAccount.deposit(100.0);
		savingsAccount.endYearUpdate();
		assertEquals(100.0 * (1 + 0.10), savingsAccount.getBalance(), epsilon,
				"The account balance was incorrect after interest was added");
	}
}
