package com.rjconsultores.ventaboletos.relatorios.utilitarios;

import java.sql.Connection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.rjconsultores.ventaboletos.relatorios.render.RenderRelatorioJasper;

import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

/**
 * @author Bruno H. G. Gouvea <bruno@rjconsultores.com.br>
 * 
 */
public abstract class Relatorio {

	private static Logger log = LogManager.getLogger(Relatorio.class);
	private static final String DEFAULT_BASE_DIR = "/com/rjconsultores/ventaboletos/relatorios";
	private static final String FILTRO_POR_TODOS = "-1";
	
	protected static final String BAIXA_FINAL = "baixaFinal";
	protected static final String BAIXA_INICIAL = "baixaInicial";
	protected static final String FEC_FINAL = "fecFinal";
	protected static final String FEC_INICIO = "fecInicio";
	protected static final String EMPRESA_ID = "empresaId";
	protected static final String PUNTOVENTA_ID = "puntoventaId";
	protected static final String NUMPUNTOVENTA = "NUMPUNTOVENTA";
	protected static final String DATA_FINAL = "DATA_FINAL";
	protected static final String DATA_INICIAL = "DATA_INICIAL";
	protected static final String FECHAMENTOCNTCORRENTE_ID = "fechamentocntcorrenteId";

	private Connection conexao;
	protected Map<String, Object> parametros;
	protected RenderRelatorioJasper render;
	private IDataSource customDataSource;
	private DataSource dataSource;
	private IParametros processadorParametros;
	private Set<String> infoMsg;
	private JRBeanCollectionDataSource collectionDataSource;
	private String[] nomeSubReporte;
	private String baseDir;
	protected Boolean customXls;
	
	protected Relatorio(Connection conexao) {
		this.conexao = conexao;
		this.infoMsg = new HashSet<String>();
	}

	protected Relatorio(Map<String, Object> parametros, Connection conexao) {
		this.parametros = parametros;
		this.conexao = conexao;
		this.infoMsg = new HashSet<String>();
	}
	
	protected Relatorio(Map<String, Object> parametros, Connection conexao, String... nomeSubReporte) {
		this.parametros = parametros;
		this.conexao = conexao;
		this.infoMsg = new HashSet<String>();
		setNomeSubReporte(nomeSubReporte);
	}

	public Connection getConexao() {
		return conexao;
	}

	public void setConexao(Connection conexao) {
		this.conexao = conexao;
	}

	public String getNome() {
		return this.getClass().getSimpleName();
	}

	public boolean isCustomDataSource() {
		return this.customDataSource != null;

	}

	public boolean isCollectionDataSource() {
		return this.collectionDataSource != null;

	}

	public Map<String, Object> getParametros() {
		return parametros;
	}

	public JRBeanCollectionDataSource getCollectionDataSource() {
		return collectionDataSource;
	}

	public void setCollectionDataSource(JRBeanCollectionDataSource collectionDataSource) {
		this.collectionDataSource = collectionDataSource;
	}

	/**
	 * @return the customDataSource
	 */
	public IDataSource getCustomDataSource() {
		return customDataSource;
	}

	/**
	 * @param iDataSource
	 *            the customDataSource to set
	 */
	public void setCustomDataSource(IDataSource iDataSource) {
		setCustomDataSource(true, iDataSource);
	}

	/**
	 * @param iDataSource
	 *            the customDataSource to set
	 */
	public void setCustomDataSource(boolean closeConnection, IDataSource iDataSource) {
		this.customDataSource = iDataSource;
		if (closeConnection) {
			closeConnection();
		}
	}

	public IParametros getProcessadorParametros() {
		return processadorParametros;
	}

	public void setProcessadorParametros(IParametros processadorParametros) {
		this.processadorParametros = processadorParametros;
	}

	protected abstract void processaParametros() throws Exception;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.rjconsultores.ventaboletos.relatorios.utilitarios.IRenderRelatorio#getConteudo()
	 */
	public byte[] getConteudo(SaidaRelatorio saida) throws Exception {
		byte[] conteudo = null;
		try {

			if (this.render == null) {
				this.processaParametros();
				this.render = new RenderRelatorioJasper(this);
			}

			conteudo = this.render.render(saida, (customXls == null ? false : customXls));

		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}

		return conteudo;

	}
	
	protected boolean possuiFiltroTodos(String parametro) {
		String ids = (String)parametros.get(parametro);
		for (int i = 0; i < ids.split(", ").length; i++) {
			if (FILTRO_POR_TODOS.equals(ids.split(", ")[i])) {
				return true;
			}
		}
		return false;
	}

	public Set<String> getInfoMsg() {
		return infoMsg;
	}

	public void addInfoMsg(String msg) {
		this.infoMsg.add(msg);
	}

	public String[] getNomeSubReporte() {
		return nomeSubReporte;
	}

	public void setNomeSubReporte(String[] nomeSubReporte) {
		this.nomeSubReporte = nomeSubReporte;
	}

	public void closeConnection() {
		try {
			if (getConexao() != null && !getConexao().isClosed()) {
				getConexao().close();
				log.info("Conexão relatorio fechada");
			}
		} catch (Exception e) {
			log.error("Erro ao fechar a conexion", e);
		}
	}

	public String getBaseDir() {
		//setado como parametro em RenderRelatorioJasper com a chave "BASE_DIR"
		return baseDir == null ? DEFAULT_BASE_DIR : baseDir;
	}

	public void setBaseDir(String baseDir) {
		this.baseDir = baseDir;
	}

	public Boolean isCustomXls() {
		return customXls;
	}

	public void setCustomXls(Boolean customXls) {
		this.customXls = customXls;
	}

	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}
	
	
}