/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.triz.trizservice.service.impl;

import com.triz.trizservice.modeles.AnneeFiscale;
import com.triz.trizservice.modeles.Etablissement;
import com.triz.trizservice.modeles.ServiceEtablissementUser;
import com.triz.trizservice.service.DaoService;
import com.triz.trizservice.modeles.ServiceFonctiongroupe;
import com.triz.trizservice.modeles.ServiceFonctionnaliter;
import com.triz.trizservice.modeles.ServiceGroupe;
import com.triz.trizservice.modeles.ServiceIncrementation;
import com.triz.trizservice.modeles.ServiceMember;
import com.triz.trizservice.modeles.ServiceUser;
import com.triz.trizservice.modeles.ServicehistoriqueConnection;
import com.triz.trizservice.modeles.ServiceWilaya;
import com.triz.trizservice.modeles.ServiceHistoriqueManipulation;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import javax.persistence.NoResultException;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

/**
 *
 * @author abder_000
 */
@Repository()
public class DaoServiceImpl implements DaoService {

    @Resource(name = "sessionFactory")
    SessionFactory sessionFactory;

    private Session getCurrentSession() {
        if (sessionFactory.getCurrentSession() == null) {
            return sessionFactory.openSession();
        }
        sessionFactory.getCurrentSession().clear();
        return sessionFactory.getCurrentSession();
    }

    @Override
    public List<ServiceUser> getAllUsers() {
        return getCurrentSession().createCriteria(ServiceUser.class).list();
    }

    @Override
    public List<ServiceFonctionnaliter> getAllFonctionalite() {
        return getCurrentSession().createCriteria(ServiceFonctionnaliter.class).list();
    }

    @Override
    public boolean isItTimeToChangePass() {
        return true;
    }

    @Override
    public ServiceUser getUserById(String userId) {
        return (ServiceUser) getCurrentSession()
                .createQuery("SELECT user FROM ServiceUser user WHERE user.userid = :userid")
                .setParameter("userid", userId)
                .setMaxResults(1)
                .uniqueResult();
    }

    @Override
    public List<ServiceMember> getGroupsByUser(ServiceUser user) {
        return getCurrentSession()
                .createQuery("SELECT membre FROM ServiceMember membre WHERE membre.fkUser = :user", ServiceMember.class)
                .setParameter("user", user)
                .getResultList();
    }

    @Override
    public ServiceMember getGroupByUser(ServiceUser user) {
        return getCurrentSession()
                .createQuery("SELECT membre FROM ServiceMember membre WHERE membre.fkUser = :user", ServiceMember.class)
                .setParameter("user", user)
                .setMaxResults(1)
                .uniqueResult();
    }

    @Override
    public void saveUser(ServiceUser object) {
        getCurrentSession().saveOrUpdate(object);
    }

    @Override
    public ServiceGroupe getGroupsById(String id) {
        return (ServiceGroupe) getCurrentSession().createCriteria(ServiceGroupe.class).add(Restrictions.eq("id", id)).setMaxResults(1).uniqueResult();
    }

    @Override
    public void saveGroup(ServiceGroupe object) {
        getCurrentSession().saveOrUpdate(object);
    }

    @Override
    public void saveMembership(ServiceMember object) {
        getCurrentSession().saveOrUpdate(object);
    }

    @Override
    public void saveFonctionsGroupes(ServiceFonctiongroupe object) {
        getCurrentSession().saveOrUpdate(object);
    }

    @Override
    public ServicehistoriqueConnection getLastHistoriqueConnectionByUsers(ServiceUser user) {
        return (ServicehistoriqueConnection) getCurrentSession().createCriteria(ServicehistoriqueConnection.class).add(Restrictions.eq("fkUser", user)).addOrder(Order.desc("id")).setMaxResults(1).uniqueResult();
    }

    @Override
    public ServicehistoriqueConnection getLastHistoriqueConnectionById(Long id) {
        return (ServicehistoriqueConnection) getCurrentSession().createCriteria(ServicehistoriqueConnection.class).add(Restrictions.eq("id", id)).setMaxResults(1).uniqueResult();
    }

    @Override
    public void save(ServicehistoriqueConnection historique) {
        getCurrentSession().saveOrUpdate(historique);
    }

    @Override
    public List<ServiceGroupe> getAllGroups() {
        return getCurrentSession().createCriteria(ServiceGroupe.class).add(Restrictions.eq("actif", "true")).list();
    }

    @Override
    public List<ServiceMember> getAllMembershipByUser(ServiceUser user) {
        return getCurrentSession().createCriteria(ServiceMember.class).add(Restrictions.eq("fkUser", user)).list();
    }

    @Override
    public List<ServiceFonctiongroupe> getAllFonctionsGroupesByGroupe(ServiceGroupe group) {
        return getCurrentSession().createCriteria(ServiceFonctiongroupe.class).add(Restrictions.eq("fkGroupe", group)).list();
    }

    @Override
    public List<ServiceMember> getAllMembership() {
        return getCurrentSession().createCriteria(ServiceMember.class).addOrder(Order.desc("date")).list();
    }

    @Override
    public ServiceFonctionnaliter getFonctionnaliteById(String id) {
        return (ServiceFonctionnaliter) getCurrentSession().createCriteria(ServiceFonctionnaliter.class).add(Restrictions.eq("id", id)).setMaxResults(1).uniqueResult();
    }

    @Override
    public List<ServiceFonctionnaliter> getAllFonctionnaliteServer() {
        return getCurrentSession().createCriteria(ServiceFonctionnaliter.class).list();
    }

    @Override
    public void save(ServiceFonctionnaliter object) {
        getCurrentSession().saveOrUpdate(object);
    }

    @Override
    public void save(ServiceHistoriqueManipulation object) {
        getCurrentSession().saveOrUpdate(object);
    }

    @Override
    public List<ServiceFonctiongroupe> getAllFonctionsGroups() {
        return getCurrentSession().createCriteria(ServiceFonctiongroupe.class).list();
    }

    @Override
    public List<ServiceFonctionnaliter> getFonctionServerByGroups(ServiceGroupe groupe) {
        return getCurrentSession().createQuery("select sf from ServiceFonctionnaliter sf,ServiceFonctiongroupe sfg   where   sf.id=sfg.fkFonction and sfg.fkGroupe =:groupeS").setParameter("groupeS", groupe).list();
    }

    @Override
    public List<ServiceFonctionnaliter> getFonctionServerByUsers(ServiceUser user) {
        return getCurrentSession().createQuery("select sf from ServiceFonctionnaliter sf,ServiceFonctiongroupe sfg, ServiceMember mem    where   sf.id=sfg.fkFonction and sfg.fkGroupe = mem.fkGroupe and mem.fkUser= :user ").setParameter("user", user).list();
    }

    @Override
    public ServiceFonctionnaliter getFonctionnaliteServerByFonction(String fonction) {
        return (ServiceFonctionnaliter) getCurrentSession().createCriteria(ServiceFonctionnaliter.class).add(Restrictions.eq("fonction", fonction)).setMaxResults(1).uniqueResult();
    }

    @Override
    public int genererBDD(String chemain, String nomSql) {
        return getCurrentSession().createSQLQuery("BACKUP DATABASE " + nomSql + " TO DISK = '" + chemain + "'   WITH FORMAT,  MEDIANAME = 'SQLServerBackups',  NAME = 'Full Backup of " + nomSql + "' ").executeUpdate();

    }

    @Override
    public List<ServiceMember> getAllMemberShipByUser(ServiceUser user) {
        return getCurrentSession().createQuery("select m from ServiceMember m where m.fkUser =:idUser").setParameter("idUser", user).list();
    }

    @Override
    public ServiceFonctiongroupe getFonctionGroupByFonctionIdAndGoupe(String id, ServiceGroupe group) {
        return (ServiceFonctiongroupe) getCurrentSession().createQuery("select fg from ServiceFonctiongroupe fg where fg.fkFonction.id =:fonction and fg.fkGroupe.id =:group").setParameter("fonction", id).setParameter("group", group.getId()).setMaxResults(1).uniqueResult();
    }

    @Override
    public void save(ServiceIncrementation object) {
        getCurrentSession().saveOrUpdate(object);
    }

    @Override
    public ServiceIncrementation getIncrementation() {
        return (ServiceIncrementation) getCurrentSession().createQuery("select increm from ServiceIncrementation increm").setMaxResults(1).uniqueResult();
    }

    @Override
    public ServiceIncrementation getFirstIncrementation() {
        return getCurrentSession().createQuery("SELECT s FROM ServiceIncrementation s ORDER BY s.id ASC", ServiceIncrementation.class).setMaxResults(1).getSingleResult();
    }

    @Override
    public void save(ServiceGroupe object) {
        getCurrentSession().saveOrUpdate(object);
    }

    @Override
    public void removeFonctionsGroupes(ServiceFonctiongroupe fonctionGroupe) {
        getCurrentSession().delete(fonctionGroupe);
    }

    @Override
    public List<ServicehistoriqueConnection> getListHistoriqueConnectionByUsers(ServiceUser user) {
        return getCurrentSession()
                .createQuery("select e from ServicehistoriqueConnection e where e.fkUser = :user", ServicehistoriqueConnection.class)
                .setParameter("user", user)
                .list();
    }

    @Override
    public List<ServiceHistoriqueManipulation> getListHistoriqueManipulationByUsersByEntreprise(ServiceUser user) {
        return getCurrentSession()
                .createQuery("select e from ServiceHistoriqueManipulation e where e.fkManipulateur = :user", ServiceHistoriqueManipulation.class)
                .setParameter("user", user)
                .list();
    }

    @Override
    public Etablissement getEtablissementById(String id) {
        return (Etablissement) getCurrentSession().createQuery("select ca from Etablissement ca where ca.idEtabStock = :id ").setParameter("id", id).setMaxResults(1).uniqueResult();
    }

    @Override
    public List<Etablissement> getAllStockEtablissementFromUsersEtablissementByUser(ServiceUser user) {
        CriteriaBuilder cb = getCurrentSession().getCriteriaBuilder();
        CriteriaQuery<Etablissement> cq = cb.createQuery(Etablissement.class);
        Root<ServiceEtablissementUser> root = cq.from(ServiceEtablissementUser.class);

        cq.select(root.get("fkEtablissement")) // sélectionne la relation
                .where(
                        cb.and(
                                cb.equal(root.get("fkUser"), user),
                                cb.equal(root.get("fkEtablissement").get("actif"), "true")
                        )
                );
        return getCurrentSession().createQuery(cq).getResultList();
    }

    @Override
    public ServiceEtablissementUser getAllUserEtablissementByEtablissementByUser(Etablissement etablissement, ServiceUser user) {
        return (ServiceEtablissementUser) getCurrentSession().createCriteria(ServiceEtablissementUser.class).add(Restrictions.eq("fkEtablissement", etablissement)).add(Restrictions.eq("fkUser", user)).setMaxResults(1).uniqueResult();
   }

    @Override
    public List<ServiceFonctionnaliter> getFonctionServerByUsersByEtablissement(ServiceUser user, Etablissement etablissement) {
       return getCurrentSession().createQuery("select sf from ServiceFonctionnaliter sf,ServiceFonctiongroupe sfg, ServiceMember mem    where   sf.id=sfg.fkFonction and sfg.fkGroupe= mem.fkGroupe and mem.fkUser=:user and mem.fkGroupe.fkEtablissement=:etab ").setParameter("etab", etablissement).setParameter("user", user).list();
    }

    @Override
    public ServicehistoriqueConnection getLastStockHistoriqueConnectionByUsers(ServiceUser user) {
        return (ServicehistoriqueConnection) getCurrentSession().createCriteria(ServicehistoriqueConnection.class).add(Restrictions.eq("fkUser", user)).addOrder(Order.desc("id")).setMaxResults(1).uniqueResult();
  }

    @Override
    public AnneeFiscale getAnneFiscalByEtablissementByActif(Etablissement etablissement) {
      return (AnneeFiscale)getCurrentSession().createQuery("select sf from AnneeFiscale sf  where sf.actif='true' and sf.fkEtablissement=:etab").setParameter("etab", etablissement).setMaxResults(1).uniqueResult();
    }

    @Override
    public List<ServiceWilaya> getAllWilaya() {
       return getCurrentSession().createQuery("select m from ServiceWilaya m ").list();
    }
}
