<?php

namespace WPD\Diagnostics\Checks;

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

final class EnvironmentCheck implements CheckInterface
{
    public function id()
    {
        return 'environment';
    }

    public function label()
    {
        return 'Entorno del servidor';
    }

    public function run(ScanContext $context, array $cursor)
    {
        $findings = array();
        $missing = array();
        foreach (array('json', 'hash', 'session', 'mysqli') as $extension) {
            if (!extension_loaded($extension)) {
                $missing[] = $extension;
            }
        }

        if ($missing) {
            $findings[] = new Finding(
                'environment.missing_extensions',
                'Faltan extensiones PHP necesarias',
                'problema confirmado',
                'alta',
                'Extensiones no disponibles: ' . implode(', ', $missing) . '.',
                'WordPress o la conexión con su base de datos pueden fallar si el alojamiento no ofrece estas extensiones.',
                array('No cambies archivos de WordPress.', 'Abre el selector de versión o extensiones PHP del alojamiento.', 'Activa las extensiones indicadas o solicita al proveedor que lo haga.'),
                'Vuelve a ejecutar el diagnóstico y comprueba que esta alerta desaparece.'
            );
        }

        $memory = $this->bytes((string) ini_get('memory_limit'));
        if ($memory > 0 && $memory < 67108864) {
            $findings[] = new Finding(
                'environment.low_memory',
                'El límite de memoria PHP es muy bajo',
                'causa probable',
                'alta',
                'memory_limit está configurado en ' . ini_get('memory_limit') . '.',
                'Plugins, temas o el propio WordPress pueden agotar la memoria durante el arranque.',
                array('Haz una copia de seguridad antes de cambiar la configuración.', 'Aumenta memory_limit desde el panel del alojamiento o pide al proveedor al menos 128M.', 'No añadas directivas al azar en .htaccess: algunos servidores producirían un error 500.'),
                'Recarga WordPress y revisa si desaparecen los errores de memoria.'
            );
        }

        $free = @disk_free_space($context->root());
        if (is_numeric($free) && (float) $free < 52428800) {
            $findings[] = new Finding(
                'environment.low_disk',
                'Queda muy poco espacio libre',
                'advertencia',
                'media',
                'El servidor informa de menos de 50 MiB disponibles.',
                'WordPress puede dejar de escribir cachés, sesiones, actualizaciones o registros.',
                array('Descarga una copia de seguridad.', 'Revisa el uso de disco desde el panel del alojamiento.', 'Elimina únicamente copias o registros que hayas identificado y que ya estén respaldados.'),
                'Comprueba en el alojamiento que vuelve a existir espacio suficiente.'
            );
        }

        $note = 'PHP ' . PHP_VERSION . '; memoria ' . (ini_get('memory_limit') ?: 'sin dato') . '; tiempo máximo ' . (ini_get('max_execution_time') ?: 'sin límite') . ' s.';
        return CheckResult::complete($findings, null, $note);
    }

    private function bytes($value)
    {
        $value = trim($value);
        if ($value === '' || $value === '-1') {
            return -1;
        }
        $unit = strtolower(substr($value, -1));
        $number = (int) $value;
        if ($unit === 'g') {
            return $number * 1073741824;
        }
        if ($unit === 'm') {
            return $number * 1048576;
        }
        if ($unit === 'k') {
            return $number * 1024;
        }
        return $number;
    }
}
