package com.armundia.app.utilities;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;

import com.armundia.arm_am.entity.ApOpzioni;
import com.armundia.arm_am.entity.ApOpzioniId;
import com.armundia.arm_am.services.ApLangApp;
import com.armundia.arm_am.services.DominiApp;
import com.armundia.arm_am.services.Dominio;
import com.armundia.arm_am.services.DominioGroup;
import com.armundia.arm_am.services.EnumApp;
import com.armundia.arm_am.services.OpzioniApp;
import com.armundia.core.startup.ApLangCacheMaintenance;
import com.armundia.core.startup.DominiCacheMaintenance;
import com.armundia.core.startup.OpzioniCacheMaintenance;
import com.armundia.v2.shared.datetime.TempoDiElaborazione;
import com.armundia.v2.shared.exception.ArmundiaException;
import com.armundia.v2.shared.interfaces.ISessionUser;

/**
 * Classe che si occupa di recuperare i domini, le opzioni e le traduzioni
 * 
 * @author asera
 *
 */
@RequestScoped
public class UtilitiesManager {
	private static final Logger log = Logger.getLogger(UtilitiesManager.class.getName());

	@Inject
	private OpzioniCacheMaintenance opzioniCacheMaintainer;

	@Inject
	private DominiCacheMaintenance dominiCacheMaintainer;

	@Inject
	private ApLangCacheMaintenance apLangCacheMaintenance;

	@Inject
	private ISessionUser sessionInfo;

	public UtilitiesPojo getUtilities(UtilitiesPojo auPojo) {
		log.log(Level.INFO, "START getting App utilities ");

		if (auPojo.getCodLang() == null || auPojo.getCodLang().equals("")) {
			//throw new ArmundiaException("AppUtilitiesPojo lingua non valorizzata");
			auPojo.setCodLang("EN");
		}

		String codLang;
		if (sessionInfo != null) {
			log.info("APP UTILITIES: " + sessionInfo.getUserId());
			codLang = sessionInfo.getCodLang();
		} else {
			log.info("APP UTILITIES NO USER");
			codLang = auPojo.getCodLang();
		}

		auPojo.setOpzioni(getOpzioniFromCache(auPojo.getCodiciOpzioni()));
		auPojo.setDomini(getDominiFromCache(auPojo.getCodiciDomini()));
		auPojo.setApLang(getApLangFromCache(auPojo.getCodiciApLang(), codLang));

		log.log(Level.INFO, "END getting App utilities");
		return auPojo;
	}

	private Map<String, ApOpzioni> getOpzioniFromCache(List<ApOpzioniId> codiciOpzione) {
		log.log(Level.INFO, "getOpzioniFromCache: {0}", codiciOpzione);

		HashMap<String, ApOpzioni> opzioniMap = new HashMap<>();

		List<ApOpzioni> opzioni = new ArrayList<>();
		try {
			opzioni = OpzioniApp.getInstance().getOptions(codiciOpzione);
		} catch (ArmundiaException e) {
			log.log(Level.SEVERE, "getOpzioniFromCache: exception {0}", e);
		}
		for (ApOpzioni opzione : opzioni) {
			opzioniMap.put(opzione.getId().getSezione() + "_" + opzione.getId().getOpzione(), opzione);
		}

		return opzioniMap;
	}

	public Map<String, Dominio> getDominiFromCache(List<String> codiciDomini) {
		log.log(Level.INFO, "getDominiFromCache: {0}", codiciDomini);

		List<String> dominiReali = new ArrayList<>();
		List<String> dominiFake = new ArrayList<>();

		for (String codice : codiciDomini) {
			log.fine("codice: " + codice);

			if (codice.startsWith("com.armundia.")) {
				dominiFake.add(codice);
			} else {
				dominiReali.add(codice);
			}
			//dominiReali.add(codice);
		}

		DominioGroup dg = null;
		if (sessionInfo != null) {
			//log.info(() -> String.format("sessionInfo [UserId] %s [JSessionId] %s", sessionInfo.getUserId(), sessionInfo.getJsessionId()));
			dg = DominiApp.getInstance().getGruppoDomini(dominiReali, sessionInfo.getCodLang(), false);
		} else {
			log.info("sessionInfo is NULL");
			dg = DominiApp.getInstance().getGruppoDomini(dominiReali, null, false);
		}

		HashMap<String, Dominio> domini = new HashMap<>();
		for (Dominio dominio : dg.getHashDom()) {
			domini.put(dominio.getCodCampo(), dominio);
		}

		DominioGroup dgFake = EnumApp.getInstance().getGruppoDomini(dominiFake);
		for (Dominio dominio : dgFake.getHashDom()) {
			domini.put(dominio.getCodCampo(), dominio);
		}

		return domini;
	}

	public Map<String, String> getApLangFromCache(List<String> codiciApLang, String codLang) {

		log.log(Level.INFO, String.format("getApLangFromCache: lang [%s] -  %s, ", codLang, codiciApLang));

		return ApLangApp.getInstance().getMsgByCodesLang(codiciApLang, codLang);
	}

	public void reloadOpzioni() {
		log.info("Inizio reloadOpzioni ");
		Date dataInizio = new Date();
		opzioniCacheMaintainer.reload();
		log.info("Fine reloadOpzioni [Time] " + TempoDiElaborazione.calcolaTempoDiElaborazione(dataInizio, new Date()));
	}

	public void reloadI18N() {
		log.info("Inizio reloadI18N ");
		Date dataInizio = new Date();
		apLangCacheMaintenance.reload();
		log.info("Fine reloadI18N [Time] " + TempoDiElaborazione.calcolaTempoDiElaborazione(dataInizio, new Date()));
	}

	public void reloadDomini() {
		log.info("Inizio reloadDomini");
		Date dataInizio = new Date();
		dominiCacheMaintainer.reload();
		log.info("Fine reloadDomini [Time] " + TempoDiElaborazione.calcolaTempoDiElaborazione(dataInizio, new Date()));
	}

}
