package com.heckmansoft.surjey.model.datastore;

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

import org.apache.log4j.Logger;


/**
 * Manages a transaction for a given connection.
 */
public class Transaction
{
    protected Connection connection;
    private int registeredUsers;
    private boolean commit;

    protected Logger log = Logger.getLogger(Transaction.class);

    public Transaction(Connection connection) {
        registeredUsers = 1;
        this.connection = connection;
        commit = true;
    }

    /**
     * Notify the transaction there is an additional user.
     */
    public void incrementUsers() {
        registeredUsers++;
    }

    /**
     * Finish the transaction by either commiting or rolling back
     * depending on the value of given argument.
     * @param status Whether to commit (true) or rollback (false).
     */
    public void finish(boolean status) {
        if (status) {
            commit();
        } else {
            rollback();
        }
    }


    /**
     * Attempt to commit the transaction.
     * Does not commit if there are still currently users of the transaction.
     * Will rollback if any other user has attempted a rollback.
     */
    public void commit() {
        // Don't commit if some previous user instructed us to rollback
        if (commit == false) rollback();

        // Decrement the number of registered users
        registeredUsers--;

        // Don't proceed if there are still
        // more registered users of the current connection.
        if (registeredUsers > 0) return;

        try {
            connection.commit();

        } catch (SQLException e) {
            log.debug(e);
            throw new RuntimeException(e);
        }

    }

    /**
     * Attempt to rollback the transaction.
     * Does not rollback if there are still currently users of the transaction.
     */
    public void rollback() {
        // Decrement the number of registered users
        registeredUsers--;

        // Record that we need to rollback
        commit = false;

        // Don't proceed if there are still
        // more registered users of the current connection.
        if (registeredUsers > 0) return;

        try {
            connection.rollback();

        } catch (SQLException e) {
            log.debug(e);
            throw new RuntimeException(e);
        }

    }

}
