<?php

declare(strict_types=1);

namespace App\Framework\Logging\Handlers;

use App\Framework\Config\Environment;
use App\Framework\Logging\Formatter\JsonFormatter;
use App\Framework\Logging\LogHandler;
use App\Framework\Logging\LogLevel;
use App\Framework\Logging\LogRecord;
use App\Framework\Logging\Security\SensitiveDataRedactor;

/**
 * Docker-optimierter JSON Handler für strukturierte Container-Logs
 *
 * Schreibt strukturierte JSON-Logs nach STDOUT für Docker Log-Aggregation.
 * Ideal für Production-Deployments mit Elasticsearch, Datadog, etc.
 *
 * Features:
 * - Compact JSON (eine Zeile pro Log)
 * - Alle Aggregator-Felder (@timestamp, severity, environment, host, service)
 * - STDOUT für Docker's JSON File Logging Driver
 * - Minimale Latenz durch direkte echo-Ausgabe
 *
 * Docker Log Kommandos:
 * - docker logs <container> --tail 50
 * - docker logs <container> --follow
 * - docker logs <container> --since 10m
 *
 * Mit jq formatieren:
 * - docker logs <container> 2>&1 | jq .
 * - docker logs <container> 2>&1 | jq 'select(.level == "ERROR")'
 * - docker logs <container> 2>&1 | jq -r '[.timestamp, .level, .message] | @tsv'
 */
final readonly class DockerJsonHandler implements LogHandler
{
    private JsonFormatter $formatter;
    private LogLevel $minLevel;
    private bool $prettyPrint;

    public function __construct(
        ?Environment $env = null,
        ?string $serviceName = null,
        LogLevel|int $minLevel = LogLevel::DEBUG,
        bool $prettyPrint = false,
        bool $redactSensitiveData = false,
        ?SensitiveDataRedactor $redactor = null
    ) {
        $this->formatter = new JsonFormatter(
            prettyPrint: $prettyPrint,
            includeExtras: true,
            flattenContext: true,
            env: $env,
            serviceName: $serviceName,
            redactSensitiveData: $redactSensitiveData,
            redactor: $redactor
        );

        $this->minLevel = $minLevel instanceof LogLevel ? $minLevel : LogLevel::fromValue($minLevel);
        $this->prettyPrint = $prettyPrint;
    }

    public function isHandling(LogRecord $record): bool
    {
        // Nur in CLI-Umgebung (Docker Container)
        if (PHP_SAPI !== 'cli') {
            return false;
        }

        return $record->level->value >= $this->minLevel->value;
    }

    public function handle(LogRecord $record): void
    {
        $json = ($this->formatter)($record);

        // Direkt nach STDOUT für Docker's JSON File Logging Driver
        echo $json . PHP_EOL;
    }

    /**
     * Setzt minimales Log-Level
     */
    public function setMinLevel(LogLevel|int $level): self
    {
        $minLevel = $level instanceof LogLevel ? $level : LogLevel::fromValue($level);

        return new self(
            env: null, // Environment wird vom Formatter gespeichert
            serviceName: null,
            minLevel: $minLevel,
            prettyPrint: $this->prettyPrint
        );
    }
}
