package simplejpa;

import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import simplejpa.exceptions.NonexistentEntityException;

/**
 * @author Daniel "3ICE" Berezvai
 */
public class MoonJpaController implements Serializable {

  public MoonJpaController(EntityManagerFactory emf) {
    this.emf = emf;
  }
  private EntityManagerFactory emf = null;

  public EntityManager getEntityManager() {
    return emf.createEntityManager();
  }

  public void create(Moon moon) {
    EntityManager em = null;
    try {
      em = getEntityManager();
      em.getTransaction().begin();
      em.persist(moon);
      em.getTransaction().commit();
    } finally {
      if (em != null) {
        em.close();
      }
    }
  }

  public void edit(Moon moon) throws NonexistentEntityException, Exception {
    EntityManager em = null;
    try {
      em = getEntityManager();
      em.getTransaction().begin();
      moon = em.merge(moon);
      em.getTransaction().commit();
    } catch (Exception ex) {
      String msg = ex.getLocalizedMessage();
      if (msg == null || msg.length() == 0) {
        Long id = moon.getId();
        if (findMoon(id) == null) {
          throw new NonexistentEntityException("The moon with id " + id +
                                               " no longer exists.");
        }
      }
      throw ex;
    } finally {
      if (em != null) {
        em.close();
      }
    }
  }

  public void destroy(Long id) throws NonexistentEntityException {
    EntityManager em = null;
    try {
      em = getEntityManager();
      em.getTransaction().begin();
      Moon moon;
      try {
        moon = em.getReference(Moon.class, id);
        moon.getId();
      } catch (EntityNotFoundException enfe) {
        throw new NonexistentEntityException("The moon with id " + id +
                                             " no longer exists.", enfe);
      }
      em.remove(moon);
      em.getTransaction().commit();
    } finally {
      if (em != null) {
        em.close();
      }
    }
  }

  public List<Moon> findMoonEntities() {
    return findMoonEntities(true, -1, -1);
  }

  public List<Moon> findMoonEntities(int maxResults, int firstResult) {
    return findMoonEntities(false, maxResults, firstResult);
  }

  private List<Moon> findMoonEntities(boolean all, int maxResults,
                                      int firstResult) {
    EntityManager em = getEntityManager();
    try {
      CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
      cq.select(cq.from(Moon.class));
      Query q = em.createQuery(cq);
      if (!all) {
        q.setMaxResults(maxResults);
        q.setFirstResult(firstResult);
      }
      return q.getResultList();
    } finally {
      em.close();
    }
  }

  public Moon findMoon(Long id) {
    EntityManager em = getEntityManager();
    try {
      return em.find(Moon.class, id);
    } finally {
      em.close();
    }
  }

  public int getMoonCount() {
    EntityManager em = getEntityManager();
    try {
      CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
      Root<Moon> rt = cq.from(Moon.class);
      cq.select(em.getCriteriaBuilder().count(rt));
      Query q = em.createQuery(cq);
      return ((Long) q.getSingleResult()).intValue();
    } finally {
      em.close();
    }
  }

}
