<?php
/**
 * ssl_cron.php — Verificação de certificados SSL e alertas de expiração
 * Executa diariamente. Verifica hosts com ssl_check_enabled = TRUE.
 */
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/includes/functions.php';

$pdo = db();

// Busca IPs com verificação SSL ativa
$stmt = $pdo->query("
    SELECT mi.*, u.timezone
    FROM monitored_ips mi
    JOIN users u ON u.id = mi.user_id
    WHERE mi.active = TRUE
      AND mi.ssl_check_enabled = TRUE
      AND (mi.ssl_last_checked_at IS NULL OR mi.ssl_last_checked_at < NOW() - INTERVAL '12 hours')
    LIMIT 500
");
$ips = $stmt->fetchAll();

if (!$ips) {
    echo "Nenhum IP com verificação SSL ativa.\n";
    exit;
}

$checked = 0;
$alerts  = 0;

foreach ($ips as $ip) {
    $host = $ip['host'];
    // Extrai hostname limpo (sem porta, sem http://)
    $hostname = preg_replace('#^https?://#', '', $host);
    $hostname = explode(':', $hostname)[0];
    $hostname = explode('/', $hostname)[0];

    if (empty($hostname)) continue;

    try {
        $expires = ssl_get_expiry_date($hostname);
        $pdo->prepare("
            UPDATE monitored_ips
            SET ssl_expires_at = ?, ssl_last_checked_at = NOW()
            WHERE id = ?
        ")->execute([$expires ? $expires->format('Y-m-d') : null, $ip['id']]);

        if ($expires) {
            $daysLeft = (int)$expires->diff(new DateTimeImmutable())->days;
            $expired  = $expires < new DateTimeImmutable();
            if ($expired) $daysLeft = -$daysLeft;

            // Alerta se expirar em menos de 30, 14 ou 7 dias (ou já expirou)
            $shouldAlert = ($daysLeft <= 30);
            if ($shouldAlert) {
                $channels = get_alert_channels((int)$ip['id']);
                $expStr   = $expires->format('d/m/Y');
                $subject  = $expired
                    ? "[MonitorPing] ⚠️ SSL EXPIRADO: {$ip['label']} ({$hostname})"
                    : "[MonitorPing] SSL expira em {$daysLeft} dias: {$ip['label']} ({$hostname})";
                $msgText  = $expired
                    ? "O certificado SSL de {$hostname} EXPIROU em {$expStr}."
                    : "O certificado SSL de {$hostname} expira em {$daysLeft} dias ({$expStr}).";

                $htmlMsg = "
<!DOCTYPE html><html lang='pt-BR'><body style='background:#f5f7fb;padding:24px;font-family:Arial,sans-serif;'>
<div style='max-width:480px;margin:0 auto;background:#fff;border-radius:16px;padding:28px;border:1px solid #e2e8f0;'>
  <div style='text-align:center;margin-bottom:16px;font-size:32px;'>" . ($expired ? '🔴' : '⚠️') . "</div>
  <h2 style='text-align:center;color:#0f172a;margin:0 0 8px;'>" . h($expired ? 'SSL Expirado!' : 'SSL Expirando em Breve') . "</h2>
  <p style='color:#64748b;text-align:center;margin:0 0 20px;'>" . h($msgText) . "</p>
  <table width='100%' style='border:1px solid #e2e8f0;border-radius:10px;border-collapse:collapse;font-size:14px;'>
    <tr><td style='padding:10px 14px;background:#f8fafc;font-weight:600;border-bottom:1px solid #e2e8f0;'>Host</td>
        <td style='padding:10px 14px;border-bottom:1px solid #e2e8f0;'>" . h($hostname) . "</td></tr>
    <tr><td style='padding:10px 14px;background:#f8fafc;font-weight:600;border-bottom:1px solid #e2e8f0;'>Expira em</td>
        <td style='padding:10px 14px;border-bottom:1px solid #e2e8f0;'>" . h($expStr) . "</td></tr>
    <tr><td style='padding:10px 14px;background:#f8fafc;font-weight:600;'>Dias restantes</td>
        <td style='padding:10px 14px;color:" . ($expired ? '#ef4444' : ($daysLeft <= 7 ? '#ef4444' : '#f59e0b')) . ";font-weight:700;'>" . ($expired ? 'EXPIRADO' : $daysLeft) . " dias</td></tr>
  </table>
</div>
</body></html>";

                foreach ($channels as $ch) {
                    if (!$ch['active']) continue;
                    if ($ch['type'] === 'email') {
                        $err = null;
                        send_email_message($ch['target'], $subject, $msgText, $err, $htmlMsg);
                    } elseif ($ch['type'] === 'telegram') {
                        send_telegram_message(
                            get_system_setting('telegram_bot_token', ''),
                            $ch['target'],
                            "🔒 *SSL Alert* — " . ($expired ? "EXPIRADO" : "expira em {$daysLeft} dias") . "\n*Host:* {$hostname}\n*Data:* {$expStr}"
                        );
                    }
                }
                $alerts++;
            }
        }
        $checked++;
    } catch (Throwable $e) {
        mp_log('warning', "SSL check falhou para {$hostname}: " . $e->getMessage());
    }
}

echo "SSL check: {$checked} verificados, {$alerts} alertas enviados.\n";

/**
 * Retorna a data de expiração do certificado SSL de um host.
 */
function ssl_get_expiry_date(string $hostname): ?DateTimeImmutable {
    $context = stream_context_create([
        'ssl' => [
            'capture_peer_cert' => true,
            'verify_peer'       => true,
            'verify_peer_name'  => true,
        ]
    ]);

    $client = @stream_socket_client(
        "ssl://{$hostname}:443",
        $errno, $errstr, 10,
        STREAM_CLIENT_CONNECT, $context
    );

    if (!$client) return null;

    $params = stream_context_get_params($client);
    fclose($client);

    $cert = $params['options']['ssl']['peer_certificate'] ?? null;
    if (!$cert) return null;

    $certInfo = openssl_x509_parse($cert);
    if (!isset($certInfo['validTo_time_t'])) return null;

    return new DateTimeImmutable('@' . $certInfo['validTo_time_t']);
}
