package example;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public final class Transfer {
    private Transfer() {}

    public static void debit(int amountCents, String entryKey) throws SQLException {
        try (Connection connection = Database.open()) {
            connection.setAutoCommit(false);
            try {
                debitOn(connection, amountCents, entryKey);
                connection.commit();
            } catch (SQLException | RuntimeException | Error failure) {
                Database.rollback(connection, failure);
                throw failure;
            }
        }
    }

    // The caller supplies one connection and owns the surrounding transaction.
    public static void debitOn(Connection connection, int amountCents, String entryKey) throws SQLException {
        if (amountCents <= 0) throw new IllegalArgumentException("Amount must be positive");
        try (PreparedStatement update = connection.prepareStatement(
                "update account set balance_cents = balance_cents - ? where id = 1 and balance_cents >= ?")) {
            update.setInt(1, amountCents);
            update.setInt(2, amountCents);
            if (update.executeUpdate() != 1) throw new IllegalStateException("Account missing or insufficient balance");
        }
        try (PreparedStatement insert = connection.prepareStatement(
                "insert into ledger(entry_key, account_id, delta_cents) values (?, 1, ?)")) {
            insert.setString(1, entryKey);
            insert.setInt(2, -amountCents);
            insert.executeUpdate();
        }
    }
}
