#!/usr/bin/env php
<?php

declare(strict_types=1);

function erro(string $mensagem, int $codigo = 1): never
{
    fwrite(STDERR, "catalogo: {$mensagem}\n");
    exit($codigo);
}

function projetoRaiz(): string
{
    return dirname(__DIR__);
}

function gravarJsonAtomico(string $path, array $dados): void
{
    $dir = dirname($path);
    if (!is_dir($dir) && !mkdir($dir, 0775, true)) {
        erro("não foi possível criar diretório de resposta: {$dir}");
    }

    $tmp = $path . '.tmp.' . getmypid();
    $json = json_encode($dados, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
    if (file_put_contents($tmp, $json, LOCK_EX) === false || !rename($tmp, $path)) {
        @unlink($tmp);
        erro("não foi possível gravar resposta local");
    }
}

function postarResposta(string $url, array $dados): array
{
    $json = json_encode($dados, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    if ($json === false) {
        return ['enviada' => false, 'erro' => 'json inválido'];
    }

    $ch = curl_init($url);
    if ($ch === false) {
        return ['enviada' => false, 'erro' => 'curl indisponível'];
    }

    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Accept: application/json',
        ],
        CURLOPT_POSTFIELDS => $json,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15,
    ]);

    $corpo = curl_exec($ch);
    $erroCurl = curl_error($ch);
    $codigoHttp = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return [
        'enviada' => $erroCurl === '' && $codigoHttp >= 200 && $codigoHttp < 300,
        'http' => $codigoHttp,
        'erro' => $erroCurl,
        'retorno' => is_string($corpo) ? $corpo : '',
    ];
}

function listarCatalogo(string $root): array
{
    $dir = $root . '/escuta/catalogo-mensagens';
    if (!is_dir($dir)) {
        erro("catálogo não encontrado: {$dir}");
    }

    $arquivos = glob($dir . '/*.json') ?: [];
    sort($arquivos, SORT_STRING);

    $out = [];
    foreach ($arquivos as $arquivo) {
        $dados = json_decode((string)file_get_contents($arquivo), true);
        if (!is_array($dados)) {
            continue;
        }

        if (($dados['ativa'] ?? false) !== true) {
            continue;
        }

        $codigo = (string)($dados['id'] ?? pathinfo($arquivo, PATHINFO_FILENAME));
        $out[] = [
            'codigo' => $codigo,
            'ativa' => true,
            'entrada' => $dados['entrada'] ?? new stdClass(),
            'saida' => $dados['saida'] ?? new stdClass(),
            'endresposta' => $dados['endresposta'] ?? null,
        ];
    }

    return $out;
}

if ($argc !== 3 || $argv[1] !== '--ler-mensagem') {
    erro('uso: conectores/catalogo --ler-mensagem <arquivo-mensagem>', 2);
}

$arquivoMensagem = $argv[2];
if (!is_file($arquivoMensagem)) {
    erro("arquivo de mensagem não encontrado: {$arquivoMensagem}", 2);
}

$mensagem = json_decode((string)file_get_contents($arquivoMensagem), true);
if (!is_array($mensagem)) {
    erro('mensagem inválida', 2);
}

$entrada = $mensagem['entrada'] ?? [];
if (!is_array($entrada) || ($entrada['listar-catalogo-mensagens'] ?? null) !== true) {
    erro('entrada inválida: informe listar-catalogo-mensagens=true', 2);
}

$root = projetoRaiz();
$id = (string)($mensagem['id'] ?? pathinfo($arquivoMensagem, PATHINFO_FILENAME));
$resposta = [
    'status' => 'ok',
    'conector' => 'catalogo',
    'mensagem' => (string)($mensagem['mensagem'] ?? ''),
    'id' => $id,
    'timestamp_resposta' => gmdate('Y-m-d\TH:i:s\Z'),
    'catalogo_mensagens' => listarCatalogo($root),
];

$endresposta = trim((string)($mensagem['endresposta'] ?? ''));
if ($endresposta !== '') {
    $resposta['envio_resposta'] = postarResposta($endresposta, $resposta);
}

gravarJsonAtomico($root . '/escuta/espaco/respostas/' . preg_replace('/[^A-Za-z0-9._-]/', '-', $id) . '.json', $resposta);

echo json_encode($resposta, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
exit(0);
