

package gov.va.med.cds.persistence.hibernate.common;


import gov.va.med.cds.exception.ErrorCodeEnum;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.usertype.CompositeUserType;

/**
 * Class to be used for VistA queries (often secondary sub queries) using a composite id
 * 
 * @author DNS   talbom
 *
 */
public class VistaPharmacyCompositeRowIdUserType
    implements
        CompositeUserType, Serializable
{

    /**
	 * 
	 */
	private static final long serialVersionUID = 6632424983748096407L;
	private BigDecimal PRESCRIPTION;
	private BigDecimal CHILDSUB1;


	public BigDecimal getPRESCRIPTION() {
		return PRESCRIPTION;
	}



	public void setPRESCRIPTION(BigDecimal pRESCRIPTION) {
		PRESCRIPTION = pRESCRIPTION;
	}



	public BigDecimal getCHILDSUB1() {
		return CHILDSUB1;
	}



	public void setCHILDSUB1(BigDecimal cHILDSUB1) {
		CHILDSUB1 = cHILDSUB1;
	}



	@Override
    public Object nullSafeGet( ResultSet rs, String[] identity, SessionImplementor session, Object owner )
        throws HibernateException,
            SQLException
    {
        //TODO - don't believe we need or care about both keys of the composite on the get method, only the set method for queries - for now just return one value
        Long idValue = null;
        if ( rs != null && rs.getString( identity[0] ) != null )
        {
        	BigDecimal value = new BigDecimal(rs.getString( identity[0]));
        	idValue = value.longValue();
        }
               
        return idValue;
    }


    
    public void nullSafeSet( PreparedStatement st, Object value, int index, SessionImplementor sessionImplementor )
            throws HibernateException,
                SQLException
        {
            //this method is implemented to set query parameters in the sql for a read - but not to write data to vista.
            if ( value == null )
            {
                st.setNull( index, StandardBasicTypes.BIG_DECIMAL.sqlType() );
                st.setNull( index+1, StandardBasicTypes.BIG_DECIMAL.sqlType() );
            }
            else
            {            
            	if(value instanceof BigDecimal){
            		st.setBigDecimal(index, (BigDecimal)value);
            		st.setBigDecimal(index+1, (BigDecimal)value);
            	}
            	else if(value instanceof Long){
            		st.setBigDecimal(index, new BigDecimal((Long)value));
            		st.setBigDecimal(index+1, new BigDecimal((Long)value));
            	}
            	
            }
        }


    @Override
    public boolean isMutable( )
    {
        return false;
    }


    @Override
    public Object replace( Object original, Object target, SessionImplementor session, Object owner )
        throws HibernateException
    {
        return original;
    }


    @Override
    public void setPropertyValue( Object component, int property, Object value )
        throws HibernateException
    {
        throw new UnsupportedOperationException( "VistaIdentityUserType setPropertyValue method not implemented." );

    }


    @Override
    public Object assemble( Serializable cached, SessionImplementor session, Object owner )
        throws HibernateException
    {
        return cached;
    }


    @Override
    public Object deepCopy( Object value )
        throws HibernateException
    {
        return value;
    }


    @Override
    public Serializable disassemble( Object value, SessionImplementor session )
        throws HibernateException
    {
        return ( Serializable )value;
    }


    @Override
    public boolean equals( Object x, Object y )
        throws HibernateException
    {
        if ( x == null )
        {
            return false;
        }

        return ( x == y );
    }


    @Override
    public String[] getPropertyNames( )
    {
        return new String[] {""};
    }


    @Override
    public Type[] getPropertyTypes( )
    {
        return new Type[] { StandardBasicTypes.STRING };
    }


    @Override
    public Object getPropertyValue( Object component, int property )
        throws HibernateException
    {
        throw new UnsupportedOperationException( new MethodNotImplementedException( ErrorCodeEnum.METHOD_NOT_IMPLEMENTED, this.getClass().getName() ) );
    }


    @Override
    public int hashCode( Object x )
        throws HibernateException
    {
        if ( x == null )
        {
            return 0;
        }

        return x.hashCode();
    }


    @Override
    public Class<BigDecimal> returnedClass( )
    {
        return BigDecimal.class;
    }
}
