package gov.va.vinci.dart.db.util;

import gov.va.vinci.dart.service.DartObjectFactory;

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

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.hibernate.Criteria;
import org.hibernate.internal.SessionImpl;

public class HibernateDAO {
	
	public static void flush() {
		// find the Hibernate session for this thread
		EntityManager mgr = DartObjectFactory.getInstance().getSessionManager().findEntityManagerForThread();

		mgr.flush();
	}
	
	public static Object findById(final Class<?> clz, final int primaryKey) {

		// find the Hibernate session for this thread
		EntityManager mgr = DartObjectFactory.getInstance().getSessionManager().findEntityManagerForThread();

		return mgr.find(clz, primaryKey);
	}
	
	public static Object findById(final Class<?> clz, final long primaryKey) {

		// find the Hibernate session for this thread
		EntityManager mgr = DartObjectFactory.getInstance().getSessionManager().findEntityManagerForThread();

		return mgr.find(clz, primaryKey);
	}
	
	public static Query createQuery(final String query) {
		EntityManager mgr = DartObjectFactory.getInstance().getSessionManager().findEntityManagerForThread();

		return mgr.createQuery(query);
	}
	
	public static Query createNativeQuery(final String query) {
		EntityManager mgr = DartObjectFactory.getInstance().getSessionManager().findEntityManagerForThread();

		return mgr.createNativeQuery(query);
	}

	public static Query createNativeQuery(final String query, final Class<?> resultClass) {
		EntityManager mgr = DartObjectFactory.getInstance().getSessionManager().findEntityManagerForThread();

		return mgr.createNativeQuery(query, resultClass);
	}
	
	public static CallableStatement createCallableStatement(final String query) throws SQLException {
		EntityManager mgr = DartObjectFactory.getInstance().getSessionManager().findEntityManagerForThread();

		SessionImpl sessionImpl = ((SessionImpl)mgr.getDelegate());
		Connection conn = sessionImpl.connection();
		
		CallableStatement stmt = conn.prepareCall(query);
		
		return stmt;
	}
	
	public static Query createNamedQuery(final String name) {
		EntityManager mgr = DartObjectFactory.getInstance().getSessionManager().findEntityManagerForThread();

		return mgr.createNamedQuery(name);
	}
	
	public static Criteria createCriteria(final Class<?> clz) {
		
		// find the Hibernate session for this thread
		EntityManager mgr = DartObjectFactory.getInstance().getSessionManager().findEntityManagerForThread();
		
		SessionImpl sessionImpl = ((SessionImpl)mgr.getDelegate());
		return sessionImpl.createCriteria(clz);
	}
	
	public static void save(Object obj) {
		EntityManager mgr = DartObjectFactory.getInstance().getSessionManager().findEntityManagerForThread();
		mgr.persist(obj);
	}
	
	public static void delete(Object obj) {
		EntityManager mgr = DartObjectFactory.getInstance().getSessionManager().findEntityManagerForThread();
		mgr.remove(obj);
	}
}
