package com.rjconsultores.ventaboletos.utilerias;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.rjconsultores.ventaboletos.dao.FeriadoDAO;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.Estado;

@Service("feriadoCache")
@Scope(value = "prototype")
public class FeriadoCache {

	private static Logger log = LogManager.getLogger(FeriadoCache.class);

	@Autowired
	private FeriadoDAO feriadoDAO;
	private Map<KeyFeriadoMap, Boolean> mapFeriado;

	public FeriadoCache() {
		mapFeriado = new LinkedHashMap<KeyFeriadoMap, Boolean>();
	}

	public boolean ehFeriado(Date dataFeriado, Empresa empresa, Estado estadoOrigem) {
		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		String strDataFeriado = sdf.format(dataFeriado);
		KeyFeriadoMap key = new KeyFeriadoMap(strDataFeriado, empresa.getEmpresaId(), estadoOrigem.getEstadoId());

		Boolean ehFeriado = mapFeriado.get(key);
		
		log.debug("ehFeriado="+ehFeriado);
		
		if (ehFeriado == null) {
			ehFeriado = feriadoDAO.ehFeriado(new java.sql.Date(dataFeriado.getTime()), empresa, estadoOrigem);

			mapFeriado.put(key, ehFeriado);
		}

		log.debug("data feriado = " + strDataFeriado + "; empresa = " + empresa.getNombempresa() + "; estado = " + estadoOrigem.getNombestado() + "; eh feriado = " + ehFeriado);

		return ehFeriado;
	}

	public void limpar() {
		log.debug("limpeza de cache de feriados");
		
		mapFeriado.clear();
	}
	
	public void limparData(Date dataFeriado, Integer empresaId, Integer estadoId) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
			String strDataFeriado = sdf.format(dataFeriado);
			
			log.info(String.format("Removendo feriado, data: "+ strDataFeriado +", empresaId: "+ empresaId+", estadoId:  " + estadoId));
			
			KeyFeriadoMap key = new KeyFeriadoMap(strDataFeriado, empresaId, estadoId);
			
			mapFeriado.remove(key);
		} catch (Exception e) {
			log.error("Erro ao remover Deriado de cache: ", e);
		}
	}

	class KeyFeriadoMap {
		private String dataFeriado;
		private Integer empresaId;
		private Integer estadoOrigemId;

		public KeyFeriadoMap(String dataFeriado, Integer empresaId, Integer estadoOrigemId) {
			super();
			this.dataFeriado = dataFeriado;
			this.empresaId = empresaId;
			this.estadoOrigemId = estadoOrigemId;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + getOuterType().hashCode();
			result = prime * result + ((dataFeriado == null) ? 0 : dataFeriado.hashCode());
			result = prime * result + ((empresaId == null) ? 0 : empresaId.hashCode());
			result = prime * result + ((estadoOrigemId == null) ? 0 : estadoOrigemId.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			KeyFeriadoMap other = (KeyFeriadoMap) obj;
			if (!getOuterType().equals(other.getOuterType()))
				return false;
			if (dataFeriado == null) {
				if (other.dataFeriado != null)
					return false;
			} else if (!dataFeriado.equals(other.dataFeriado))
				return false;
			if (empresaId == null) {
				if (other.empresaId != null)
					return false;
			} else if (!empresaId.equals(other.empresaId))
				return false;
			if (estadoOrigemId == null) {
				if (other.estadoOrigemId != null)
					return false;
			} else if (!estadoOrigemId.equals(other.estadoOrigemId))
				return false;
			return true;
		}

		private FeriadoCache getOuterType() {
			return FeriadoCache.this;
		}
	}
}
