// Source File Name:   ControleAC.java

package br.com.pirus.ac.controles;

import br.com.pirus.ac.comunicacao.FuncoesDLL;
import br.com.pirus.ac.interfaces.ControleACListener;
import br.com.pirus.ac.utils.Utils;
import com.sun.jna.Native;
import com.sun.xml.internal.messaging.saaj.util.Base64;
import java.util.Calendar;
import java.util.Random;

// Referenced classes of package br.com.pirus.ac.controles:
//            ControleLogs, ControleArquivos, ControleDados

public class ControleAC
{

    public ControleAC()
    {
        dll = (FuncoesDLL)Native.loadLibrary("SAT", br/com/pirus/ac/comunicacao/FuncoesDLL);
        resultado = null;
        tempoResposta = 0L;
    }

    public String processarComandoPing()
    {
        resultado = null;
        (new Thread(new Runnable() {

            public void run()
            {
                ControleLogs.logar("------------- PINGAR -------------");
                try
                {
                    resultado = dll.ConsultarSAT(ControleAC.getRandom(6));
                }
                catch(Exception e)
                {
                    ControleLogs.logar("Falha no Driver do SAT-CFe.");
                }
                ControleLogs.logar("------------- FIM PINGAR -------------");
            }

            final ControleAC this$0;

            
            {
                this$0 = ControleAC.this;
                super();
            }
        }
)).start();
        aguardaRecebimentoSincrono(30000L);
        return Utils.tratarResultadoPing(resultado);
    }

    public void processarComandoPing(ControleACListener janela)
    {
        resultado = null;
        tempoResposta = 0L;
        ControleLogs.logar("------------- PINGAR -------------");
        long inicio = Calendar.getInstance().getTimeInMillis();
        try
        {
            if(ControleArquivos.existeArquivo("C:/SAT/SAT.dll"))
                resultado = dll.ConsultarSAT(getRandom(6));
            else
                throw new Exception();
        }
        catch(Exception e)
        {
            ControleLogs.logar("Falha no Driver do SAT-CFe.");
            return;
        }
        tempoResposta = Calendar.getInstance().getTimeInMillis() - inicio;
        ControleLogs.logar("------------- FIM PINGAR -------------");
        if(janela != null)
            janela.tratarResultado(resultado);
    }

    public void processarComandoDesligarSAT(ControleACListener janela)
    {
        resultado = null;
        tempoResposta = 0L;
        ControleLogs.logar("------------- DESLIGAR SAT -------------");
        long inicio = Calendar.getInstance().getTimeInMillis();
        try
        {
            if(ControleArquivos.existeArquivo("C:/SAT/SAT.dll"))
                resultado = dll.DesligarSAT();
            else
                throw new Exception();
        }
        catch(Exception e)
        {
            ControleLogs.logar("Falha no Driver do SAT-CFe.");
            return;
        }
        tempoResposta = Calendar.getInstance().getTimeInMillis() - inicio;
        ControleLogs.logar("------------- FIM DESLIGAR SAT -------------");
        if(janela != null)
            janela.tratarResultado(resultado);
    }

    public void processarComandoEmitirCFe(ControleACListener janela, String codigoAtivacao, String dados)
    {
        resultado = null;
        tempoResposta = 0L;
        ControleLogs.logar("-------------EMITIR CFE-------------");
        String aviso = null;
        int numeroSessao = getRandom(6);
        long inicio = Calendar.getInstance().getTimeInMillis();
        try
        {
            ControleArquivos.escreverCaracteresArquivo("c:/cfe.txt", dados.toCharArray());
            resultado = dll.EnviarDadosVenda(numeroSessao, codigoAtivacao, dados);
        }
        catch(Exception e)
        {
            ControleLogs.logar("Falha no Driver do SAT-CFe.");
            return;
        }
        tempoResposta = Calendar.getInstance().getTimeInMillis() - inicio;
        ControleLogs.logar("-------------FIM EMITIR CFE-------------");
        String partes[] = ControleDados.quebrarString(resultado, "|");
        if(resultado.startsWith("06000") && partes.length == 9)
        {
            String doc = Base64.base64Decode(partes[5]);
            String vCFe = doc.substring(doc.indexOf("<vCFe>") + "<vCFe>".length(), doc.indexOf("</vCFe>"));
            String chave = partes[8];
            ControleArquivos.escreverCaracteresArquivo("C:/AC/Cancelamento/infCanc.txt", (new StringBuilder(String.valueOf(chave))).append("|").append(vCFe).toString().toCharArray());
            ControleArquivos.escreverCaracteresArquivo("C:/AC/lastCFe.xml", doc.toCharArray());
        }
        ControleArquivos.escreverCaracteresArquivo((new StringBuilder("C:/AC/Sessoes/")).append(numeroSessao).append(".txt").toString(), resultado.toCharArray());
        ControleArquivos.escreverCaracteresArquivo("C:/AC/Sessoes/sessao.txt", (new StringBuilder(String.valueOf(numeroSessao))).toString().toCharArray());
        if(janela != null)
            janela.tratarResultado(resultado);
    }

    public void processarComandoCancelarCFe(ControleACListener janela, String codigoAtivacao, String chaveAcesso, String dados)
    {
        resultado = null;
        tempoResposta = 0L;
        ControleLogs.logar("-------------CANCELAR CFE-------------");
        long inicio = Calendar.getInstance().getTimeInMillis();
        try
        {
            resultado = dll.CancelarUltimaVenda(getRandom(6), codigoAtivacao, chaveAcesso, dados);
        }
        catch(Exception e)
        {
            ControleLogs.logar("Falha no Driver do SAT-CFe.");
            return;
        }
        tempoResposta = Calendar.getInstance().getTimeInMillis() - inicio;
        ControleLogs.logar("-------------FIM CANCELAR CFE-------------");
        if(janela != null)
            janela.tratarResultado(resultado);
    }

    public void processarComandoConsultarCFe(ControleACListener janela, String codigoAtivacao, int numeroSessao)
    {
        resultado = null;
        tempoResposta = 0L;
        ControleLogs.logar("-------------CONSULTAR CFE-------------");
        long inicio = Calendar.getInstance().getTimeInMillis();
        try
        {
            resultado = dll.ConsultarNumeroSessao(getRandom(6), codigoAtivacao, numeroSessao);
        }
        catch(Exception e)
        {
            ControleLogs.logar("Falha no Driver do SAT-CFe.");
            return;
        }
        tempoResposta = Calendar.getInstance().getTimeInMillis() - inicio;
        ControleLogs.logar("-------------FIM CONSULTAR CFE-------------");
        if(resultado.startsWith("11000"))
            ControleArquivos.escreverCaracteresArquivo((new StringBuilder("C:/AC/Sessoes/")).append(numeroSessao).append(".txt").toString(), resultado.substring(resultado.indexOf("06")).toCharArray());
        if(janela != null)
            janela.tratarResultado(resultado);
    }

    public static int getRandom(int tamanho)
    {
        int max = 1;
        for(int i = 0; i < tamanho; i++)
            max *= 10;

        int resultado = (new Random()).nextInt(max);
        if(resultado >= max / 10)
            return resultado;
        else
            return getRandom(tamanho);
    }

    private String aguardaRecebimentoSincrono(long tempo)
    {
        try
        {
            long tempoAtual = System.currentTimeMillis();
            for(long t0 = tempoAtual; tempoAtual - t0 < tempo && resultado == null; tempoAtual = System.currentTimeMillis())
                Thread.sleep(200L);

            if(resultado == null)
                resultado = "Timeout.";
        }
        catch(Exception e)
        {
            resultado = "Timeout.";
        }
        return resultado;
    }

    public long getTempoResposta()
    {
        return tempoResposta;
    }

    private FuncoesDLL dll;
    private String resultado;
    private long tempoResposta;


}
