/**
 * Copyright © 2010, Res Interactive, LLC. All Rights Reserved.
 */
package com.tootsville.user;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.starhope.appius.except.NotFoundException;
import org.starhope.appius.except.NotReadyException;
import org.starhope.appius.game.AppiusClaudiusCaecus;
import org.starhope.appius.mb.Currency;
import org.starhope.appius.user.Nomenclator;
import org.starhope.appius.user.UserRecord;
import org.starhope.appius.util.AppiusConfig;
import org.starhope.appius.util.DataRecordFlushManager;
import org.starhope.util.LibMisc;

/**
 * the additional details that define a Toot that aren't common to
 * Appius Claudius Caecus User class
 *
 * @author brpocock@star-hope.org
 */
public class TootUserTrailerSQLLoader implements TootUserTrailerLoader {

    /**
     * @see org.starhope.appius.util.RecordLoader#changed(org.starhope.appius.util.DataRecord)
     */
    @Override
    public void changed (final TootUserTrailer changedRecord) {
        DataRecordFlushManager.update (this, changedRecord);
    }

    /**
     * @see org.starhope.util.HasSubversionRevision#getSubversionRevision()
     */
    @Override
    public String getSubversionRevision () {
        return "$Rev: 4078 $";
    }

    /**
     * @see org.starhope.appius.util.RecordLoader#initializeStorage(java.lang.String)
     */
    @Override
    public void initializeStorage (final String storageURL)
    throws NotReadyException {
        // no op. AppiusConfig does all of this for us.
    }

    /**
     * @see org.starhope.appius.util.RecordLoader#isRealtime()
     */
    @Override
    public boolean isRealtime () {
        return false;
    }

    /**
     * @see org.starhope.appius.util.RecordLoader#loadRecord(int)
     */
    @Override
    public TootUserTrailer loadRecord (final int id)
    throws NotFoundException {
        Connection con = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        TootUserTrailer toot = null;
        // System.err.println ("TootUserTrailerSQLLoader::loadRecord("
        // + id + ")");
        try {
            con = AppiusConfig.getDatabaseConnection ();
            st = con
            .prepareStatement ("SELECT ID, tootTimeLeft, tootTimeLeftMinutes, tootTimeRefill, tootTimerType, basic8Choice FROM users WHERE ID=?");
            st.setInt (1, id);
            rs = st.executeQuery ();
            if (rs.next ()) {
                toot = new TootUserTrailer (this);
                set (toot, rs);
                // toot.setGun (TooterShooter.class) XXX
                return toot;
            }
        } catch (final SQLException e) {
            // No op...
        } finally {
            LibMisc.closeAll (rs, st, con);
        }
        throw new NotFoundException (String.valueOf (id));
    }

    /**
     * @see org.starhope.appius.util.RecordLoader#loadRecord(java.lang.String)
     */
    @Override
    public TootUserTrailer loadRecord (final String identifier)
    throws NotFoundException {
        Connection con = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        TootUserTrailer toot = null;
        try {
            con = AppiusConfig.getDatabaseConnection ();
            st = con
            .prepareStatement ("SELECT ID, tootTimeLeft, tootTimeLeftMinutes, tootTimeRefill, tootTimerType, basic8Choice FROM users WHERE userName=?");
            st.setString (1, identifier);
            rs = st.executeQuery ();
            if (rs.next ()) {
                toot = new TootUserTrailer (this);
                set (toot, rs);
                return toot;
            }
        } catch (final SQLException e) {
            // No op...
        } finally {
            LibMisc.closeAll (rs, st, con);
        }
        throw new NotFoundException (identifier);
    }

    /**
     * @see org.starhope.appius.util.RecordLoader#refresh(org.starhope.appius.util.DataRecord)
     */
    @Override
    public void refresh (final TootUserTrailer record) {
        // TODO Auto-generated method stub

    }

    /**
     * @see org.starhope.appius.util.RecordLoader#removeRecord(org.starhope.appius.util.DataRecord)
     */
    @Override
    public void removeRecord (final TootUserTrailer record) {
        // TODO Auto-generated method stub brpocock@star-hope.org
        AppiusClaudiusCaecus.reportBug("unimplemented RecordLoader<TootUserTrailer>::removeRecord (brpocock@star-hope.org, Jul 22, 2010)");

    }

    /**
     * @see org.starhope.appius.util.RecordLoader#saveRecord(org.starhope.appius.util.DataRecord)
     */
    @Override
    public void saveRecord (final TootUserTrailer record) {
        Connection con = null;
        PreparedStatement st = null;
        UserRecord user;
        try {
            user = Nomenclator.getDataRecord (UserRecord.class, record
                    .getID ());
        } catch (final NotFoundException e1) {
            AppiusClaudiusCaecus
            .reportBug (
                    "Caught a NotFoundException in TootUserTrailerSQLLoader.saveRecord ",
                    e1);
            return;
        }
        try {
            con = AppiusConfig.getDatabaseConnection ();
            st = con
            .prepareStatement ("UPDATE users SET peanuts=?, tootTimeLeft=?, tootTimeLeftMinutes=?, tootTimeRefill=?, tootTimerType=?, basic8Choice=? WHERE ID=?");
            st.setBigDecimal (1, user.getCurrency (Currency
                    .getPeanuts ()));
            st.setBigDecimal (2, new BigDecimal (record
                    .getTootTimeLeft ()));
            st.setBigDecimal (3, new BigDecimal (record
                    .getTootTimeLeftMinutes ()));
            st.setBigDecimal (4, new BigDecimal (record
                    .getTootTimeRefill ()));
            st.setString (5, record.isTootTimerDay () ? "D" : record
                    .isTootTimerMonth () ? "M" : "ERR");
            st
            .setString (6, String.valueOf (record
                    .getBasic8Choice ()));
            st.setInt (7, record.getID ());
            st.executeUpdate ();
        } catch (final SQLException e) {
            // No op...
        } finally {
            LibMisc.closeAll (st, con);
        }
    }

    /**
     * @param toot trailer record
     * @param resultSet result set with values to use
     * @throws SQLException if the data set is invalid
     */
    private void set (final TootUserTrailer toot,
            final ResultSet resultSet) throws SQLException {
        toot.setTootTimeLeft (resultSet.getBigDecimal ("tootTimeLeft")
                .intValue ());
        toot.setTootTimeLeftMinutes (resultSet.getBigDecimal (
        "tootTimeLeftMinutes").intValue ());
        toot.setTootTimeRefill (resultSet.getBigDecimal (
        "tootTimeRefill").intValue ());
        final String timerType = resultSet.getString ("tootTimerType");
        toot.setTootTimerDay ("D".equals (timerType));
        toot.setTootTimerMonth ("M".equals (timerType));
        if ( ! (toot.isTootTimerDay () ^ toot.isTootTimerMonth ())) {
            throw AppiusClaudiusCaecus
            .fatalBug ("invalid tootTimerType value returned for "
                    + toot.getID ());
        }
        toot.setID (resultSet.getInt ("ID"));
        toot.markAsLoaded ();
        // System.err.println ("-> set record properly");
    }
}
