<?php

namespace WPD\Security;

final class EvidenceNormalizer
{
    public function logLine($line, $category, $root)
    {
        $labels = array(
            'memory' => 'Memoria PHP agotada',
            'parse' => 'Error de sintaxis PHP',
            'database' => 'Conexión de base de datos rechazada',
            'dependency' => 'Dependencia de código ausente',
            'fatal' => 'Error fatal de PHP',
        );
        $parts = array(isset($labels[$category]) ? $labels[$category] : 'Error de PHP');
        $location = $this->location((string) $line, (string) $root);
        if ($location['path'] !== null) {
            $parts[] = $location['path'];
        }
        if ($location['line'] !== null) {
            $parts[] = 'línea ' . $location['line'];
        }
        $symbol = $this->symbol((string) $line);
        if ($symbol !== null) {
            $parts[] = 'símbolo ' . $symbol;
        }
        return implode(' · ', $parts);
    }

    private function location($line, $root)
    {
        $normalizedLine = str_replace('\\', '/', $line);
        $normalizedRoot = rtrim(str_replace('\\', '/', $root), '/');
        $path = null;
        $lineNumber = null;

        if ($normalizedRoot !== '' && preg_match('~' . preg_quote($normalizedRoot, '~') . '/([A-Za-z0-9._/\-]+\.php)(?:\s+on\s+line\s+|:)?(\d+)?~i', $normalizedLine, $match)) {
            $candidate = ltrim($match[1], '/');
            if (strpos($candidate, '../') === false) {
                $path = $candidate;
            }
            if (!empty($match[2])) {
                $lineNumber = (int) $match[2];
            }
        } elseif (preg_match('~(?:[A-Za-z]:)?/[A-Za-z0-9._/\-]+\.php~', $normalizedLine)) {
            $path = '[RUTA_EXTERNA]';
        }

        if ($lineNumber === null && preg_match('/\bon\s+line\s+(\d+)\b/i', $line, $match)) {
            $lineNumber = (int) $match[1];
        }
        return array('path' => $path, 'line' => $lineNumber);
    }

    private function symbol($line)
    {
        $patterns = array(
            '/Call to undefined function\s+([A-Za-z_\\\\][A-Za-z0-9_\\\\:\-]{0,99})/i',
            '/Class\s+[\'\"]([A-Za-z_\\\\][A-Za-z0-9_\\\\:\-]{0,99})[\'\"]\s+not found/i',
        );
        foreach ($patterns as $pattern) {
            if (preg_match($pattern, $line, $match)) {
                return substr($match[1], 0, 100);
            }
        }
        return null;
    }
}

