package pointers_errors

import (
	"testing"
)

//https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully

func assertNoError(t testing.TB, got error) {
	t.Helper()
	if got != nil {
		t.Fatal("got an error but didn't want one")
	}
}

func TestWallet(t *testing.T) {

	assertBalance := func(t *testing.T, wallet Wallet, want Bitcoin) {
		t.Helper()
		got := wallet.Balance()

		if got != want {
			t.Errorf("got %s want %s", got, want)
		}
	}

	assertError := func(t testing.TB, got, want error) {
		t.Helper()
		if got == nil {
			// Fata; will stop the test if called. We do this because we
			// don't want to make any more assertions, otherwise we would try
			// to access a nil pointer and hit a panic
			t.Fatal("wanted error but didn't get one")
		}
		// cast error to string and compare
		// if got.Error() != want {
		// 	t.Errorf("got %q, want %q", got, want)
		// }
		if got != want {
			t.Errorf("got %q, want %q", got, want)
		}
	}

	t.Run("deposit", func(t *testing.T) {
		wallet := Wallet{}

		wallet.Deposit(10)

		assertBalance(t, wallet, Bitcoin(10))
	})

	t.Run("withdraw", func(t *testing.T) {
		wallet := Wallet{balance: Bitcoin(20)}

		// This was found by using
		// go install github.com/kisielk/errcheck@latest
		// and using `errcheck .` on our code. Could make
		// a great pre-commit hook.
		err := wallet.Withdraw(Bitcoin(10))

		assertNoError(t, err)
		assertBalance(t, wallet, Bitcoin(10))

	})

	t.Run("withdraw insufficient funds", func(t *testing.T) {
		startingBalance := Bitcoin(20)
		wallet := Wallet{balance: startingBalance}
		err := wallet.Withdraw(Bitcoin(100))

		assertBalance(t, wallet, startingBalance)
		assertError(t, err, ErrInsufficientFunds)

	})
}
