package com.blstream.myhoard.db.dao;

import com.blstream.myhoard.biz.exception.MyHoardException;
import com.blstream.myhoard.db.model.ItemDS;
import com.blstream.myhoard.db.model.MediaDS;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public class ItemDAO implements ResourceDAO<ItemDS> {

    private SessionFactory sessionFactory;

    @Override
    public List<ItemDS> getList() {
        Session session = sessionFactory.getCurrentSession();
        return session.createCriteria(ItemDS.class).list();
    }

    @Override
    public List<ItemDS> getList(Map<String, String> args) {
        return null;
    }

    @Override
    public ItemDS get(int id) {
        Session session = sessionFactory.getCurrentSession();
        return (ItemDS)session.createCriteria(ItemDS.class)
                .add(Restrictions.eq("id", id))
                .uniqueResult();
    }

    @Override
    public void create(ItemDS obj) {
        Session session = sessionFactory.getCurrentSession();
        List<Integer> ids = new ArrayList<>();
        for (MediaDS i : obj.getMedia())
            ids.add(i.getId());
        // czy można to prościej zrealizować?
        if (!ids.isEmpty() && ((Long)session.createQuery("select count(*) from MediaDS as m where m.item is not null and m.id in (:ids)").setParameterList("ids", ids).iterate().next()).longValue() > 0)
            throw new MyHoardException(2, "Próba przepisania Media do innego elementu.");
        session.save(obj);
    }

    @Override
    public void update(ItemDS obj) {
        ItemDS object = get(obj.getId());
        object.updateObject(obj);

        Session session = sessionFactory.getCurrentSession();
        if (obj.isMediaAltered()) {
            List<Integer> media = new ArrayList<>();
            for (MediaDS i : obj.getMedia())
                media.add(i.getId());
            Set<MediaDS> result = new HashSet<>(media.isEmpty() ? Collections.EMPTY_SET : (List<MediaDS>)session.createCriteria(MediaDS.class)
                .add(Restrictions.in("id", media))
                .list());
            Set<MediaDS> remaining = object.getMedia();
            remaining.removeAll(result);
            for (MediaDS i : remaining)   // pozostałe media trzeba usunąć
                session.delete(i);
            object.setMedia(result);
        }
        object.setModifiedDate(Calendar.getInstance().getTime());
        session.update(object);

        obj.updateObject(object);
    }

    @Override
    public void remove(int id) {
        Session session = sessionFactory.getCurrentSession();
        session.delete(session.createCriteria(ItemDS.class)
                .add(Restrictions.eq("id", id))
                .uniqueResult());
    }

    @Override
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public ItemDS getByAccess_token(String access_token) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public ItemDS getByUsername(String username) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public ItemDS getByRefresh_token(String refresh_token) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

}

@@ -271,31 +271,8 @@
 ns;%0A
-import java.util.Date;%0A
 impo
@@ -364,39 +364,8 @@
 et;%0A
-import org.hibernate.Criteria;%0A
 impo
@@ -427,16 +427,58 @@
 actory;%0A
+import org.hibernate.criterion.MatchMode;%0A
 import o
@@ -752,33 +752,22 @@
         
-Session session =
+return
  session
@@ -785,33 +785,32 @@
 CurrentSession()
-;
 %0A        return 
@@ -802,30 +802,24 @@
         
-return session
+        
 .createC
@@ -839,16 +839,33 @@
 S.class)
+%0A                
 .list();
@@ -934,43 +934,424 @@
 ng, 
-String%3E args) %7B%0A        return null
+Object%3E params) %7B%0A        return sessionFactory.getCurrentSession()%0A                .createCriteria(ItemDS.class)%0A                .add(Restrictions.ilike(%22name%22, (String)params.get(%22name%22), MatchMode.ANYWHERE))%0A                .add(Restrictions.ilike(%22description%22, (String)params.get(%22name%22), MatchMode.ANYWHERE))%0A                .add(Restrictions.eq(%22collection%22, params.get(%22collection%22)))%0A                .list()
 ;%0A  
@@ -1409,34 +1409,31 @@
         
-Session session = 
+return (ItemDS)
 sessionF
@@ -1450,33 +1450,32 @@
 CurrentSession()
-;
 %0A        return 
@@ -1467,38 +1467,24 @@
         
-return (ItemDS)session
+        
 .createC
@@ -3994,224 +3994,6 @@
  %7D%0A%0A
-    @Override%0A    public ItemDS getByRefresh_token(String refresh_token) %7B%0A        throw new UnsupportedOperationException(%22Not supported yet.%22); //To change body of generated methods, choose Tools %7C Templates.%0A    %7D%0A%0A
 %7D%0A

Update ItemDAO.java