<?php

namespace WPD\Diagnostics\Checks;

use WPD\Diagnostics\CheckInterface;
use WPD\Domain\CheckResult;
use WPD\Domain\Finding;
use WPD\Domain\ScanContext;

final class ConfigurationCheck implements CheckInterface
{
    public function id()
    {
        return 'configuration';
    }

    public function label()
    {
        return 'Configuración y servidor web';
    }

    public function run(ScanContext $context, array $cursor)
    {
        $findings = array();
        $config = $context->config();
        if (!$config['complete']) {
            $findings[] = new Finding(
                'configuration.static_parse_incomplete',
                'No se pudo leer toda la conexión desde wp-config.php',
                'advertencia',
                'media',
                $config['error'] ?: 'Faltan valores reconocibles.',
                'La configuración puede usar variables de entorno o código personalizado. La herramienta no lo ejecuta por seguridad.',
                array('No publiques ni copies las credenciales.', 'Usa el formulario manual de la herramienta para probar la conexión.', 'Si wp-config.php está dañado, compáralo con una copia de seguridad.'),
                'Confirma que el bloque de base de datos pueda completarse.',
                'parcial'
            );
        }

        $maintenance = $context->root() . '/.maintenance';
        if (is_file($maintenance)) {
            $age = time() - (int) @filemtime($maintenance);
            $findings[] = new Finding(
                'configuration.stale_maintenance',
                'WordPress está bloqueado en modo mantenimiento',
                $age > 600 ? 'problema confirmado' : 'advertencia',
                $age > 600 ? 'alta' : 'media',
                'Existe .maintenance desde hace aproximadamente ' . max(0, (int) floor($age / 60)) . ' minutos.',
                'Una actualización interrumpida puede dejar este archivo y ocultar el sitio público.',
                array('Comprueba que no haya una actualización en curso.', 'Haz una copia de seguridad.', 'Si lleva bloqueado más de 10 minutos, elimina únicamente el archivo .maintenance de la raíz.'),
                'Recarga la web y confirma que ya no aparece el aviso de mantenimiento.'
            );
        }

        $wpConfig = $context->root() . '/wp-config.php';
        $permissions = @fileperms($wpConfig);
        if (is_int($permissions) && ($permissions & 0x0002)) {
            $findings[] = new Finding(
                'configuration.world_writable_config',
                'wp-config.php permite escritura a cualquier usuario',
                'advertencia',
                'alta',
                'Los permisos observados permiten escritura global.',
                'Es un riesgo de seguridad y facilita modificaciones accidentales o maliciosas.',
                array('Haz una copia y anota propietario y permisos actuales.', 'Corrige los permisos desde el panel o consulta al alojamiento.', 'No uses 777 como solución.'),
                'Repite el diagnóstico y confirma que desaparece la advertencia.'
            );
        }

        $htaccess = $context->guard()->safeFile($context->root() . '/.htaccess');
        if ($htaccess !== null && is_readable($htaccess) && filesize($htaccess) <= 262144) {
            $source = @file_get_contents($htaccess);
            if (is_string($source)) {
                $host = isset($_SERVER['HTTP_HOST']) ? preg_replace('/:\d+$/', '', strtolower($_SERVER['HTTP_HOST'])) : '';
                if (preg_match_all('/RewriteRule\s+\S+\s+https?:\/\/([^\/\s]+)/i', $source, $matches)) {
                    foreach ($matches[1] as $target) {
                        $targetHost = preg_replace('/:\d+$/', '', strtolower($target));
                        if ($host !== '' && $targetHost !== $host) {
                            $findings[] = new Finding(
                                'configuration.external_rewrite',
                                '.htaccess redirige hacia otro dominio',
                                'causa probable',
                                'alta',
                                'Se encontró una regla absoluta cuyo dominio de destino no coincide con el solicitado.',
                                'Una regla heredada de una migración puede impedir acceder al dominio actual.',
                                array('Descarga una copia de .htaccess.', 'Comprueba si el dominio de destino es intencionado.', 'Si no lo es, regenera las reglas de WordPress o corrige únicamente esa redirección.'),
                                'Abre el sitio en una ventana privada y confirma que permanece en el dominio correcto.'
                            );
                            break;
                        }
                    }
                }
            }
        }

        return CheckResult::complete($findings);
    }
}
