<?php
/**
 * Esse arquivo processa os dados gerados pelo webhook.php
 * @author Telic Technologies <contato@telic.com.br>
 * @license PRIVATE
 */

if(php_sapi_name()!=="cli") {
    http_response_code(401);
    die("Restrito para execução via CLI!");
}

// métodos para log e requisições
require 'lib/lib.php';

// caso o diretório da fila não exista, crie ele
if(!is_dir(__DIR__ . '/fila')) mkdir(__DIR__ . '/fila');

$diretorio = __DIR__ . '/fila';

while( true ) {
    // lendo arquivos do diretório
    $directory_iterator = new RecursiveDirectoryIterator(
        $diretorio, 
        FilesystemIterator::SKIP_DOTS
    );
    $iterator = new RecursiveIteratorIterator($directory_iterator);

    foreach ($iterator as $arquivo) {
        TLog::log("Enviando arquivo \"{$arquivo->getFileName()}\" para telic.");

        // faço a leitura e a decodificação do arquivo
        $conteudo = file_get_contents($arquivo);
        if(!$conteudo){
            TLog::log("[ERRO ARQUIVO] Não foi possível ler o conteúdo do arquivo. Vazio?");
            continue;
        }
        $payload = json_decode($conteudo,true);
        $decode_error = json_last_error();
        if($decode_error !== JSON_ERROR_NONE){
            switch ($decode_error) {
                case JSON_ERROR_DEPTH: TLog::log('[ERRO JSON]  Maximum stack depth exceeded'); break;
                case JSON_ERROR_STATE_MISMATCH: TLog::log('[ERRO JSON]  Underflow or the modes mismatch'); break;
                case JSON_ERROR_CTRL_CHAR: TLog::log('[ERRO JSON]  Unexpected control character found'); break;
                case JSON_ERROR_SYNTAX: TLog::log('[ERRO JSON]  Syntax error, malformed JSON'); break;
                case JSON_ERROR_UTF8: TLog::log('[ERRO JSON]  Malformed UTF-8 characters, possibly incorrectly encoded'); break;
                default: TLog::log("[ERRO JSON]  Unknown error: $decode_error"); break;
            }
            // Tentativa solução N. #2
            if($decode_error == JSON_ERROR_SYNTAX){
                // Tentativa de solução
                $finalJson = 0;
                $chaves = 0;
                for ($i = 0; $i < strlen($conteudo); $i++){
                    if($conteudo[$i] == '{'){
                        $chaves+=1;
                    } else if($conteudo[$i] == '}'){
                        $chaves-=1;
                    }
                    if(($i > 0) && ($chaves == 0)){ // Hipotético fim do JSON
                        $finalJson = $i;
                        break;
                    }
                }
                $descarte = substr($conteudo, $finalJson+1);
                $conteudo = substr($conteudo, 0, $finalJson+1);
                TLog::log("[JSON CORRECTION] Descartado: $descarte");
                TLog::log("[JSON CORRECTION] Conteúdo após correção: $conteudo");
                if(strlen($conteudo) > 2){
                    $payload = json_decode($conteudo,true);
                    if(json_last_error() == JSON_ERROR_NONE){
                        TLog::log("[JSON CORRECTION] Após processo de recuperação, JSON corrigido.");
                    } else { // Continuou com erro
                        TLog::log("[ERRO JSON CORRECTION]  Mesmo com correção, o JSON final apresentou erros. Ignorando.");
                        continue;
                    }
                } else // JSON obtido não tem tamanho válido (0)
                    continue;
            } else // Quaquer outro erro, sem solução
                continue;
        }
        $param_token = $payload["params"]["token"];
        if(!$param_token){
            TLog::log("[ERRO TOKEN] Arquivo \"{$arquivo->getFileName()}\" não contém um Token nos padrões. Ignorando arquivo. objeto=".$conteudo);
            continue;
        }

        // efetuo a requição para o producer da telic
        $isOk = TCall::makeRequest($payload["data"], $param_token);

        // caso dê erro eu paro a execução do iterator
        if(!$isOk) {
            TLog::log("[ERRO] Falha no envio. Tentando novamente.");
            break;
        }

        // caso dê certo, apago o arquivo
        unlink($arquivo);
    }

    // aguarda 1s para reprocessar.
    sleep(1);
}