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

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import  org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;

import com.rjconsultores.ventaboletos.entidad.Constante;
import com.rjconsultores.ventaboletos.entidad.Custom;
import com.rjconsultores.ventaboletos.entidad.Imagem;
import com.rjconsultores.ventaboletos.service.ConstanteService;
import com.rjconsultores.ventaboletos.service.CustomService;
import com.rjconsultores.ventaboletos.service.ImagemService;
import com.rjconsultores.ventaboletos.web.utilerias.spring.AppContext;

/**
 * Clase con las propriedad especificas de los clientes
 * 
 * @author Administrador
 */

public class ApplicationProperties {
	private static final Logger log = LogManager.getLogger(ApplicationProperties.class);
	private static ApplicationProperties INSTANCE;
	private static Properties p;
	private static final String PATH_IMAGENES = "/com/rjconsultores/ventaboletos/web/cliente/imagenes/";

	private Boolean readOnlyConnection = Boolean.TRUE;
	
	private ApplicationProperties() {
		p = new Properties();
		this.readConfiguration();
		this.readConfigurationToDatabase();
		this.readReadOnlyConnection();
	}

	public static ApplicationProperties getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new ApplicationProperties();
		}

		return INSTANCE;
	}

	private void readConfiguration() {
		try {

			InputStream is = new ClassPathResource("/com/rjconsultores/ventaboletos/web/cliente/conf/application.properties").getInputStream();
			p.load(is);
			is.close();
		} catch (IOException e) {
			log.error(e);
		}
	}
	
	/**
     * Insere na tabela de custom os registros que existem no Enum, o valor inicial ao inserir de cada custom é baseado no arquivo de propriedades 
     * {@code database.properties}, caso não exista é inserido com valor {@code null}. A cada novo parâmetro no Enum será adicionado um registro na tabela de custom. não deverá  mais ser adicionado 
     * mais informações no arquivo de propriedades, somente no Enum {@code CustomEnum}.
     * @see     #CustomEnum
     */
	public void readConfigurationToDatabase() {

		try {
			CustomService customService = (CustomService) AppContext.getApplicationContext().getBean("customService");
			for (CustomEnum customEnum : CustomEnum.values()) {
				log.info("Verificando custom=" + customEnum.toString());
				if (customService.buscar(customEnum.toString()) == null) {

					Custom custom = new Custom();
					custom.setChave(customEnum.toString());
					custom.setValor(StringUtils.isNotBlank(p.getProperty(customEnum.toString()))
							? p.getProperty(customEnum.toString())
							: "false");
					custom.setSistema(Custom.TIPO_SISTEMA_ADM);
					customService.suscribir(custom);

					log.info("Adicionado custom=" + customEnum.toString());
				}
			}

		} catch (Exception e) {
			log.error("", e);
		}
	}
	
	private String getValuefromCustom(String key, String defaultValue) {

		try {
			CustomService customService = (CustomService) AppContext.getApplicationContext().getBean("customService");
			Custom custom = customService.buscar(key);
			if (custom != null) {
				String val = custom.getValor();
				return (val == null) ? defaultValue : val;
			}

		} catch (Exception e) {
			log.error("", e);
		}

		return defaultValue;

	}

	public Integer maxSizeNumCorrida() {
		String property = getValuefromCustom(CustomEnum.MAX_SIZE_NUM_CORRIDA.toString(), "-1");
		return Integer.parseInt(property);
	}
	
	/**
     * Procura a chave no banco de dados, caso exista retorna o valor, caso não exista retorna 0.
     *
     * @param   key   o valor da chave.
     * @return  o valor do custom no  banco.
     */
	public boolean isCustomHabilitado(String key) {
		String property = getValuefromCustom(key, "0");
		return property.equals("1");
	}
	
	/**
     * Procura a chave no banco de dados, caso exista retorna o valor, caso não exista retorna o valor default.
     *
     * @param   key   o valor da chave.
     * @return  o valor do custom no  banco.
     */
	public boolean isCustomHabilitado(String key, String defaultValue) {
		String property = getValuefromCustom(key, defaultValue);
		return property.equals("1") ;
	}
	
	public boolean isCustomHabilitado(String key, Boolean defaultValue) {
		String property = getValuefromCustom(key, defaultValue.toString());
		return property.equals("true") ;
	}
	
	private InputStream readImagefromCustom(String imagene) throws FileNotFoundException, IOException {

		InputStream inputStream = null;
		try {
			inputStream = new ClassPathResource(PATH_IMAGENES + imagene).getInputStream();
		} catch (FileNotFoundException fnfe) {
			throw fnfe;
		} catch (IOException e) {
			throw e;
		}
		return inputStream;
	}
	
	public void loadImageToDatabase(String empresa, boolean isGenerica) {

		try {

			String empresaNome = isGenerica ? "EMPRESA_BACKGROUND_GENERICA" : "EMPRESA_BACKGROUND";
			ImagemService imagemService = (ImagemService) AppContext.getApplicationContext().getBean("imagemService");

			if (CollectionUtils.isEmpty(imagemService.buscar(empresaNome))) {
				InputStream in = readImagefromCustom(empresa);
				if (in != null) {
					byte[] targetArray = IOUtils.toByteArray(in);

					Imagem entidad = new Imagem();
					entidad.setImagem(targetArray);
					entidad.setNombImagem(empresaNome);

					imagemService.suscribir(entidad);
				}

			}
			
			

		} catch (IOException e) {
			log.error("", e);
		}

	}
	
	public void singletonImage(){
		
		ConstanteService constanteService = (ConstanteService) AppContext.getApplicationContext().getBean("constanteService");
		ImagemService imagemService = (ImagemService) AppContext.getApplicationContext().getBean("imagemService");
		Constante constante = constanteService.buscarPorNomeConstante("IMAGENE_EMPRESA_GENERICA");
		
		if ((constante != null) && StringUtils.isNotBlank(constante.getValorconstante()) && Boolean.valueOf(constante.getValorconstante())) {
			Imagem imagemGenerica = imagemService.buscarPorNomeImagem("EMPRESA_BACKGROUND_GENERICA");
			getApplication().setImage(imagemGenerica);
		}else{
			Imagem imagem = imagemService.buscarPorNomeImagem("EMPRESA_BACKGROUND");
			getApplication().setImage(imagem);
		}
	}
	
	private Application getApplication() {
		ApplicationContext appContext = AppContext.getApplicationContext();
		BeanFactory factory = (BeanFactory) appContext;
		Application app = (Application) factory.getBean("app");
		return app;
	}

	public void readReadOnlyConnection() {
		ConstanteService constanteService = (ConstanteService) AppContext.getApplicationContext().getBean("constanteService");
		Constante constante = constanteService.buscarPorNomeConstante("READ_ONLY_CONNECTION");
		
		readOnlyConnection = Boolean.TRUE;
		
		if ((constante != null) && StringUtils.isNotBlank(constante.getValorconstante())) {
			readOnlyConnection = Boolean.valueOf(constante.getValorconstante());
		}
	}
	
	public Boolean getReadOnlyConnection() {
		return readOnlyConnection;
	}
}
