package info.bukova.isspst.dao.jpa;

import java.util.List;

import org.hibernate.NonUniqueObjectException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.core.GenericTypeResolver;

import info.bukova.isspst.dao.BaseDao;

public abstract class BaseDaoJPA<T> implements BaseDao<T> {

	protected Class<T> classTypeResolver;
	
	@SuppressWarnings("unchecked")
	public BaseDaoJPA()
	{
		this.classTypeResolver = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(), BaseDaoJPA.class);
	}
	
	@Override
	public String getEntityName() {
		String className = classTypeResolver.getSimpleName();
		return className;
	}

	
	private SessionFactory sessionFactory;
	
	public void setSessionFactory(SessionFactory factory) {
		this.sessionFactory = factory;
	}
	
	@Override
	public void add(T entity) {
		sessionFactory.getCurrentSession().save(entity);
	}

	@Override
	public void delete(T entity) {
		try {
			sessionFactory.getCurrentSession().delete(entity);
		} catch (NonUniqueObjectException e) {
			Object o = sessionFactory.getCurrentSession().merge(entity);
			sessionFactory.getCurrentSession().delete(o);
		}
	}

	@Override
	public void modify(T entity) {
		try {
			sessionFactory.getCurrentSession().update(entity);
		} catch (NonUniqueObjectException e) {
			sessionFactory.getCurrentSession().merge(entity);
		}
	}
	
	@Override
	public Session getSession() {
		return sessionFactory.getCurrentSession();
	}

	@SuppressWarnings("unchecked")
	@Override
	public T getById(int id) {
		Query q = sessionFactory.getCurrentSession().createQuery("from " + getEntityName() + " e where ID = :id");
		q.setInteger("id", id);
		return (T) q.uniqueResult();
	}
	
	@Override
	public Query getQuery(String query) {
		return sessionFactory.getCurrentSession().createQuery(query);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<T> execQuery(String query) {
		return sessionFactory.getCurrentSession().createQuery(query).list();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<T> getAll() {
		return sessionFactory.getCurrentSession().createQuery("from " + getEntityName()).list();
	}

}
