package dst.ass1.jpa.dao.impl;

import dst.ass1.jpa.dao.ICourseDAO;
import dst.ass1.jpa.model.CourseStatus;
import dst.ass1.jpa.model.ICourse;
import dst.ass1.jpa.model.impl.Course;
import dst.ass1.jpa.util.Constants;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

public class CourseDAO extends GenericDAO<Course, ICourse> implements ICourseDAO {
    public CourseDAO(EntityManager em) {
        super(em, Course.class);
    }

    @Override
    public Collection<ICourse> findOngoingAndFreeCoursesForPlatform(String platformName) {
        try {
            return em.createNamedQuery(Constants.Q_ONGOING_AND_FREE_PLATFORM_COURSES, ICourse.class)
                    .setParameter("platformName", platformName).getResultList();
        } catch (NoResultException e) {
            return null;
        }
    }

    @Override
    public Collection<ICourse> findNonCancelledCoursesBetweenStartAndEnd(Date start, Date end) {
        CriteriaBuilder b = em.getCriteriaBuilder();
        CriteriaQuery<ICourse> q = b.createQuery(ICourse.class);
        Root<Course> root = q.from(Course.class);
        final List<Predicate> andPredicates = new ArrayList<Predicate>();

        andPredicates.add(b.notEqual(root.get("status"), CourseStatus.CANCELLED));
        if (start != null) andPredicates.add(b.greaterThan(root.get("start"), start));
        if (end != null) andPredicates.add(b.lessThan(root.get("end"), end));

        q.select(root).where(b.and(andPredicates.toArray(new Predicate[andPredicates.size()])));

        List<ICourse> a = em.createQuery(q).getResultList();
        return a;
    }
}
