package com.rjconsultores.ventaboletos.rest;

import java.io.IOException;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.zkoss.zkplus.spring.SpringUtil;

import com.rjconsultores.ventaboletos.service.ConstanteService;
/**
 * @author vjcor
 *
 */
public class ContingenciaClienteRest {
	

	public enum ETipoEnvio {
		GET, POST;
	}
	
	private static final String CONSTANTE_BPE_URL = "BPE_URL";
	private static final String CREDENCIAIS = "rjconsultores:RJ#C0nsul10res@2019";
	private static final String PATH_CONSULTA_STATUS = "/BPeRS/rest/adm/contingencia/tipoEmissaoEmpresa";
	private static final String PATH_DEFINIR_STATUS = "/BPeRS/rest/adm/contingencia/definirTipoEmissaoEmpresa";

	private static final Logger log = LogManager.getLogger(ContingenciaClienteRest.class);
	
	private static ContingenciaClienteRest instance;
	
	private ContingenciaClienteRest() {
	}
	
	public static synchronized ContingenciaClienteRest getInstance() {
		if(instance == null) {
			instance = new ContingenciaClienteRest();
		}
		return instance;
	}
	
	public Integer consultar(String bpeURL, String uf, String ambiente, String cnpj) {
		try {
			return verificarStatus(getURI(bpeURL, PATH_CONSULTA_STATUS, uf, ambiente, cnpj), ETipoEnvio.GET);
		} catch (IOException e) {
			log.error(e);
		} catch (JSONException e) {
			log.error(e);
		} catch (IllegalStateException e) {
			log.error(e);
		}
		return null;
	}
	
	public Integer definir(String bpeURL,String uf, String ambiente, String cnpj, Integer idStatus) {
		try {
			return verificarStatus(getURI(bpeURL, PATH_DEFINIR_STATUS, uf, ambiente, cnpj, idStatus), ETipoEnvio.POST);
		} catch (IOException e) {
			log.error(e);
		} catch (JSONException e) {
			log.error(e);
		} catch (IllegalStateException e) {
			log.error("Erro no envio/retorno da requisicao para BPERS", e);
		}
		return null;
	}
	
	private String buscarConstanteURL() {
		return getConstanteService().buscarPorNomeConstante(CONSTANTE_BPE_URL).getValorconstante();
	}

	private ConstanteService getConstanteService() {
		return (ConstanteService) SpringUtil.getBean("constanteService");
	}

	private Integer verificarStatus(String uri, ETipoEnvio tipoEnvio) throws IOException, JSONException, IllegalStateException {
		HttpClient client = new DefaultHttpClient();
		HttpUriRequest request = getRequest(uri, tipoEnvio);
		HttpResponse response = client.execute(request);

		if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK
				&& response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
			throw new IllegalStateException("Ocorreu um erro na requisição." + response.getStatusLine() !=null ? response.getStatusLine().getReasonPhrase() : "");
		}
		
		return getRetornoJSON(response);
	}

	private Integer getRetornoJSON(HttpResponse response) throws IOException, JSONException {
		HttpEntity entity = response.getEntity();

		if (entity != null) {
			String rest = EntityUtils.toString(entity);
			JSONObject result = new JSONObject(rest);
			return Integer.valueOf(result.get("tpEmis").toString());
		}
		return null;
	}

	private HttpUriRequest getRequest(String uri, ETipoEnvio tipoEnvio) {
		HttpUriRequest request = ETipoEnvio.GET.equals(tipoEnvio) ? new HttpGet(uri) : new HttpPost(uri);
		request.addHeader("Authorization", getAuthorization());
		return request;
	}

	private String getAuthorization() {
		return "Basic " + new String(Base64.encodeBase64(CREDENCIAIS.getBytes()));
	}
	
	private String getURI(String bpeURL, String path, String uf, String ambiente, String cnpj) {
		StringBuilder uri = new StringBuilder();
		uri.append(bpeURL);
		uri.append(path);
		uri.append("?uf=").append(uf);
		uri.append("&ambiente=").append(ambiente);
		uri.append("&cnpj=").append(cnpj);
		
		return uri.toString();
	}
	
	private String getURI(String bpeURL, String path, String uf, String ambiente, String cnpj, Integer idStatus) {
		StringBuilder uri = new StringBuilder();
		uri.append(getURI(bpeURL, path, uf, ambiente, cnpj));
		uri.append("&tpEmis=").append(idStatus);
		
		return uri.toString();
	}
}
