package usda.weru.weps.reports.query;

import java.sql.SQLException;
import java.sql.Types;

import systems.uom.common.USCustomary;
import si.uom.SI;
import javax.measure.Unit;

import org.apache.log4j.Logger;
import usda.weru.util.Units;
import usda.weru.util.Util;
import usda.weru.weps.fuel.Fuel;
import usda.weru.weps.fuel.FuelDAO;
import usda.weru.util.ConfigData;
import usda.weru.weps.fuel.EnergyPerVolume;
import usda.weru.weps.fuel.PricePerVolume;

/**
 *
 * @author joelevin
 */
public class FuelsResultSet extends WepsResultSet {

    private static final Logger LOGGER = Logger.getLogger(FuelsResultSet.class);

    public static final String NAME = "fuels";
    public static final String COLUMN_NAME = "name";
    public static final String COLUMN_DISPLAY = "display";
    public static final String COLUMN_DESCRIPTION = "description";
    public static final String COLUMN_DIESEL = "diesel";
    public static final String COLUMN_ENERGY = "energy";
    public static final String COLUMN_PRICE = "price";

    private final WepsConnection c_con;
    private boolean c_filled;

    /**
     *
     * @param con
     * @throws SQLException
     */
    public FuelsResultSet(WepsConnection con) throws SQLException {
        c_con = con;
        //Columns expected in the file
        addColumn(COLUMN_NAME, Types.VARCHAR, 50, 0);
        addColumn(COLUMN_DISPLAY, Types.VARCHAR, 50, 0);
        addColumn(COLUMN_DESCRIPTION, Types.VARCHAR, 250, 0);

        addColumn(COLUMN_DIESEL, Types.DOUBLE, 10, 5);
        addColumn(COLUMN_ENERGY, Types.DOUBLE, 10, 5);
        addColumn(COLUMN_PRICE, Types.DOUBLE, 10, 5);
    }

    @Override
    public String getName() {
        return NAME;
    }

    protected boolean isUSUnits() {
        return Util.USUnits.equals(c_con.getUnits());
    }

    /**
     *
     * @throws SQLException
     */
    @Override
    public synchronized void fill() throws SQLException {
        if (c_filled) {
            return;
        }
        //used as the reference fuel in the science model
        Fuel diesel = FuelDAO.getInstance().getFuel("diesel");
        double dieselEnergy = diesel.getEnergy().to(getEnergyUnit(isUSUnits())).getValue().doubleValue();
        
        Fuel[] fuels = FuelDAO.getInstance().getFuels();

        for (Fuel fuel : fuels) {
            Object[] row = createNewRow(true);

            setRowValue(row, COLUMN_NAME, fuel.getName());
            setRowValue(row, COLUMN_DISPLAY, fuel.getDisplayName());
            setRowValue(row, COLUMN_DESCRIPTION, fuel.getDescription());

            double energy = fuel.getEnergy().to(getEnergyUnit(isUSUnits())).getValue().doubleValue();
            setRowValue(row, COLUMN_ENERGY, energy);

            double price = fuel.getPrice().to(getPriceUnit(isUSUnits())).getValue().doubleValue();
            setRowValue(row, COLUMN_PRICE, price);

            setRowValue(row, COLUMN_DIESEL, energy / dieselEnergy);
        }
        c_filled = true;
    }

    //private static Unit<?> getEnergyUnit(boolean us) {
    private static Unit<EnergyPerVolume> getEnergyUnit(boolean us) {
        if (us) {
            return Units.createEnergyPerVolumeUnit(Units.DIESEL_US, USCustomary.GALLON_LIQUID);
        } else {
            return Units.createEnergyPerVolumeUnit(Units.DIESEL_SI, SI.LITRE);
        }
    }

    //private static Unit<?> getPriceUnit(boolean us) {
    private static Unit<PricePerVolume> getPriceUnit(boolean us) {
        if (us) {
            return Units.createPricePerVolumeUnit(ConfigData.USD, USCustomary.GALLON_LIQUID);
        } else {
            return Units.createPricePerVolumeUnit(ConfigData.USD, SI.LITRE);
        }
    }

    /**
     *
     * @param columnName
     * @param us
     * @return
     */
    public static String getDisplayUnits(String columnName, Boolean us) {
        if (COLUMN_ENERGY.equals(columnName)) {
            Unit<EnergyPerVolume> unit = getEnergyUnit(us);
            return unit.toString();
        } else if (COLUMN_PRICE.equals(columnName)) {
            Unit<PricePerVolume> unit = getPriceUnit(us);
            return unit.toString();
        } else if ("volume".equals(columnName)) {
            if (us) {
                return USCustomary.GALLON_LIQUID.toString();
            } else {
                return SI.LITRE.toString();
            }
        } else if ((COLUMN_ENERGY + "novolume").equals(columnName)) {
            if (us) {
                //return Units.DIESEL_US.toString();
                return ConfigData.getDefault().getData(ConfigData.FuelDefault);
            } else {
                //return Units.DIESEL_SI.toString();
                return ConfigData.getDefault().getData(ConfigData.FuelDefault);
            }
        } else if ((COLUMN_PRICE + "novolume").equals(columnName)) {
            return "USD";
        }
        return null;
    }
}
