package no.valg.valgnatt.database.dao;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import no.valg.valgnatt.database.domene.ValgType;
import no.valg.valgnatt.database.hibernate.Mandatberegning;
import no.valg.valgnatt.database.hibernate.Mandatberegning_;
import no.valg.valgnatt.database.hibernate.MandaterId;
import no.valg.valgnatt.database.hibernate.MandaterId_;

import org.hibernate.Session;
import org.springframework.stereotype.Repository;

@Repository
public class MandatberegningDao extends BaseDao<Mandatberegning, MandaterId> {

    public List<Mandatberegning> find(ValgType valgType, String valgdistriktnr, boolean prognose) {
        return find(valgType, valgdistriktnr, true, prognose);
    }

    public List<Mandatberegning> find(ValgType valgType, String valgdistriktnr, boolean likhet, boolean prognose) {

        Session session = sessionFactory.getCurrentSession();
        CriteriaBuilder cb = session.getCriteriaBuilder();
        CriteriaQuery<Mandatberegning> cq = cb.createQuery(Mandatberegning.class);
        Root<Mandatberegning> root = cq.from(Mandatberegning.class);
        List<Predicate> predicates = new ArrayList<>();
        predicates.add(cb.equal(root.get(Mandatberegning_.id).get(MandaterId_.valgtype), valgType.name()));
        predicates.add(cb.equal(root.get(Mandatberegning_.id).get(MandaterId_.prognose), prognose ? "1" : "0"));
        if (valgdistriktnr != null) {
            if (likhet) {
                predicates.add(cb.equal(root.get(Mandatberegning_.id).get(MandaterId_.valgdistriktnr), valgdistriktnr));
            } else {
                predicates.add(cb.notEqual(root.get(Mandatberegning_.id).get(MandaterId_.valgdistriktnr), valgdistriktnr));
            }
        }
        cq.select(root)
                .where(predicates.toArray(new Predicate[]{}))
                .orderBy(cb.asc(root.get(Mandatberegning_.id).get(MandaterId_.valgdistriktnr)),
                        cb.asc(root.get(Mandatberegning_.id).get(MandaterId_.partikode)));
        return session.createQuery(cq).getResultList();
    }

}
