<?php
namespace EasyChat\Library\Security;

 
final class ApiIncidentLogger {
    public static function newId(): string {
        try {
            return 'api_' . bin2hex(random_bytes(8));
        } catch (\Throwable $e) {
            return 'api_' . substr(hash('sha256', uniqid('', true)), 0, 16);
        }
    }

    public static function exceptionLine(\Throwable $exception, string $incident_id): string {
        return self::encode([
            'event' => 'api_exception',
            'incident_id' => self::incidentId($incident_id),
            'exception_class' => self::safeClass(get_class($exception)),
            'file' => self::safeFile($exception->getFile()),
            'line' => max(0, (int)$exception->getLine()),
        ]);
    }

    public static function fatalLine(array $error, string $incident_id): string {
        return self::encode([
            'event' => 'api_fatal',
            'incident_id' => self::incidentId($incident_id),
            'error_type' => max(0, (int)($error['type'] ?? 0)),
            'file' => self::safeFile((string)($error['file'] ?? '')),
            'line' => max(0, (int)($error['line'] ?? 0)),
        ]);
    }

    private static function encode(array $record): string {
        $json = json_encode($record, JSON_UNESCAPED_SLASHES);
        return is_string($json) ? $json : '{"event":"api_incident_encode_failed"}';
    }

    private static function incidentId(string $incident_id): string {
        return preg_match('/^api_[a-f0-9]{16}$/D', $incident_id) ? $incident_id : 'api_invalid';
    }

    private static function safeClass(string $class): string {
        return substr((string)preg_replace('/[^A-Za-z0-9_\\\\]/', '_', $class), 0, 120);
    }

    private static function safeFile(string $file): string {
        $name = basename(str_replace('\\', '/', $file));
        return substr((string)preg_replace('/[^A-Za-z0-9._-]/', '_', $name), 0, 128);
    }
}
