package com.rjconsultores.ventaboletos.dao.util;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.HibernateException;

/**
 * Trata a geração do ID da forma de pagamento data tabela forma de pagamento, pois não pode ultrapassar 2 digitos
 * 
 * @author Guilherme Lopes
 */
public class IdFormaPagoStore {

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

	private static final String LIMITE_ID_FORMA_PAGTO = "LIMITE_ID_FORMA_PAGTO";

	private static IdFormaPagoStore INSTANCE = new IdFormaPagoStore();

	private int indiceAtual = 1;

	private IdFormaPagoStore() {
	}

	public static IdFormaPagoStore getInstance() {
		return INSTANCE;
	}

	public synchronized Serializable getNextId(Connection connection) throws HibernateException {

		int qtdMaxima = this.buscarLimiteFormaPago(connection);

		log.info(String.format("qtdMaxima:%s", qtdMaxima));

		long idEncontrado = -1;

		PreparedStatement ps;

		try {

			ps = connection.prepareStatement("SELECT COUNT(*) AS qtd FROM FORMA_PAGO WHERE FORMAPAGO_ID = :1");

			for (; (idEncontrado == -1) && (indiceAtual <= qtdMaxima); indiceAtual++) {
				ps.setInt(1, indiceAtual);
				ResultSet rs = ps.executeQuery();
				rs.next();
				int qtd = rs.getInt("qtd");

				if (qtd == 0) {
					idEncontrado = indiceAtual;
				}
			}

		} catch (SQLException e) {
			log.error("erro ao buscar id IdFormaPago", e);
			throw new HibernateException(e);
		}

		log.info("indiceAtual=" + indiceAtual);
		log.info("idEncontrado=" + idEncontrado);

		if (indiceAtual > qtdMaxima && (idEncontrado != qtdMaxima)) {
			throw new HibernateException("A qtd de IDs permitidos para IdFormaPago foi atingido:" + qtdMaxima);
		}

		if (idEncontrado == -1) {
			throw new HibernateException("Houve algum erro ao buscar um novo ID para IdFormaPago !");
		}
		return idEncontrado;
	}

	/**
	 * Buscar novo limite de IdFormaPago.
	 * 
	 * Por padrão é 99. Com o intuito de ativar de forma gradual, foi criado uma constante para essa Função
	 * 
	 * @param connection
	 * @return
	 */
	private int buscarLimiteFormaPago(Connection connection) {
		int qtdMaxima = 99;
		PreparedStatement ps;

		log.info("buscando constante limite IdFormaPago ...");

		try {

			ps = connection.prepareStatement("SELECT VALORCONSTANTE FROM CONSTANTE WHERE NOMBCONSTANTE = :1");
			ps.setString(1, LIMITE_ID_FORMA_PAGTO);

			ResultSet rs = ps.executeQuery();

			if (rs.next()) {

				String tmp = rs.getString("VALORCONSTANTE");

				if (StringUtils.isNotBlank(tmp)) {
					qtdMaxima = Integer.parseInt(tmp);

					log.info(String.format("constante encontrada : %s", tmp));
				}
			} else {
				log.info("constante não parametrizada");
			}

			rs.close();
			ps.close();

		} catch (Throwable e) {
			log.error("erro buscar constante", e);
		}

		return qtdMaxima;
	}
}
