/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.rjconsultores.ventaboletos.dao.hibernate;

import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.rjconsultores.ventaboletos.dao.TramoServicioDAO;
import com.rjconsultores.ventaboletos.entidad.ClaseServicio;
import com.rjconsultores.ventaboletos.entidad.Parada;
import com.rjconsultores.ventaboletos.entidad.Tramo;
import com.rjconsultores.ventaboletos.entidad.TramoServicio;
import com.rjconsultores.ventaboletos.entidad.Via;

/**
 * 
 * @author Rafius
 */
@SuppressWarnings("unchecked")
@Repository("tramoServicioDAO")
public class TramoServicioHibernateDAO extends GenericHibernateDAO<TramoServicio, Integer>
		implements TramoServicioDAO {

	private static final Logger log = LogManager.getLogger(TramoServicioHibernateDAO.class);
	
	@Autowired
	public TramoServicioHibernateDAO(@Qualifier("sessionFactory") SessionFactory factory) {
		setSessionFactory(factory);
	}

	
	@Override
	public TramoServicio suscribir(TramoServicio entity) {
		
		log.info(String.format("suscribir TramoServicio: %s " , entity.toStringComplete()));
		
		return super.suscribir(entity);
	}

	public List<TramoServicio> buscarPorTramo(Tramo tramo) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));
		c.add(Restrictions.eq("tramo", tramo));

		return c.list();
	}

	public List<TramoServicio> buscarPorTramo(Tramo tramo, ClaseServicio clase) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));
		c.add(Restrictions.eq("tramo", tramo));
		c.add(Restrictions.eq("claseServicio", clase));

		return c.list();
	}

	@Override
	public TramoServicio buscar(Parada origen, Parada destino, Via via, ClaseServicio clase) {

		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));
		Criteria cTramo = c.createCriteria("tramo");
		cTramo.add(Restrictions.eq("origem", origen));
		cTramo.add(Restrictions.eq("destino", destino));
		cTramo.add(Restrictions.eq("via", via));
		cTramo.add(Restrictions.eq(ACTIVO, Boolean.TRUE));
		c.add(Restrictions.eq("claseServicio", clase));
		
		/**
		 * FIXME: O trecho de Código abaixo foi adicionado para tentar identificar um problema de duplicidade no 
		 * tramoServicio.
		 * 
		 * Deve ser temporario.
		 */

		List<TramoServicio> list = c.list();
		if (list.size() > 1){
			
			for(TramoServicio ts : list){
				log.error(String.format("Erro tramoServicio duplicado:%s", ts.toStringComplete() ));
			}
			
		}
		
		return list.isEmpty()?null:list.get(0);

	}

	@Override
	public boolean existenTiemposTramosEsquema(Integer esquemaCorridaId) {

		Query query = getSession().createQuery("select count(*) from EsquemaTramo ct where ct.activo = 1 and ct.esquemaCorrida.esquemacorridaId = :esquemaCorrida");
		query.setParameter("esquemaCorrida", esquemaCorridaId);
		Long cantTramos = HibernateFix.count(query.uniqueResult());

		StringBuilder sb = new StringBuilder("");
		sb.append("select count(*) ");
		sb.append("from ");
		sb.append("esquema_corrida ec ");
		sb.append("inner join esquema_tramo et on et.esquemacorrida_id = ec.esquemacorrida_id ");
		sb.append("inner join tramo_servicio ts on ts.tramo_id = et.tramo_id and ts.CLASESERVICIO_ID = ec.CLASESERVICIO_ID ");
		sb.append("where ");
		sb.append("et.activo = 1 ");
		sb.append("and ts.activo = 1 ");
		sb.append("and ec.esquemacorrida_id  = :esquemaCorrida");

		Query query2 = getSession().createSQLQuery(sb.toString());
		query2.setParameter("esquemaCorrida", esquemaCorridaId);

		Long cantTramosTiempos = HibernateFix.count(query2.uniqueResult());

		return cantTramos.equals(cantTramosTiempos);
	}
	
	@Override
	@Transactional
	public void limparInconsistenciasTramo() {
		
		StringBuilder sql = new StringBuilder(500);
		sql.append("update  ");
		sql.append("   tramo_servicio set activo = 0  ");
		sql.append("WHERE  ");
		sql.append("   rowid in ( select rid from (  ");
		sql.append("       select rowid rid,row_number()  ");
		sql.append("       over (partition by CLASESERVICIO_ID,TRAMO_ID order by rowid) rn  ");
		sql.append("       from tramo_servicio ");
		sql.append("       where activo = 1) ");
		sql.append("   where rn <> 1 ) ");
		sql.append("   and activo =1 ");
		Query query = getSession().createSQLQuery(sql.toString());
		int tramoServicoAtualizado = query.executeUpdate();
		log.info(" Rotina limparInconsistenciasTramo: "+tramoServicoAtualizado+" TramoServicio atualizados" );
		
		sql = new StringBuilder(500);
		sql.append("update ");
		sql.append("   orgao_tramo set activo = 0  ");
		sql.append("WHERE  ");
		sql.append("   rowid in ( select rid from (  ");
		sql.append("       select rowid rid,row_number()  ");
		sql.append("       over (partition by  CLASESERVICIO_ID,ORGAOCONCEDENTE_ID,TRAMO_ID order by rowid) rn  ");
		sql.append("       from orgao_tramo ");
		sql.append("       where activo = 1) ");
		sql.append("   where rn <> 1 ) ");
		sql.append("   and activo =1 ");

		Query query2 = getSession().createSQLQuery(sql.toString());
	    int orgaoTramoAtualizado = query2.executeUpdate();
		log.info(" Rotina limparInconsistenciasTramo: "+orgaoTramoAtualizado+" OrgaoTramo atualizados" );
	}
	
}
