<?php

namespace WPD\Security;

final class Redactor
{
    private $secrets;
    private $root;

    public function __construct(array $secrets = array(), $root = '')
    {
        $this->secrets = array_values(array_filter(array_map('strval', $secrets), function ($value) {
            return strlen($value) >= 4;
        }));
        $this->root = rtrim((string) $root, '/\\');
    }

    public function text($value)
    {
        $value = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/', ' ', (string) $value);
        $value = preg_replace('/\s+/', ' ', (string) $value);
        foreach ($this->secrets as $secret) {
            $value = str_replace($secret, '[SECRETO OCULTO]', $value);
        }
        if ($this->root !== '') {
            $value = str_replace($this->root, '[RAÍZ_WORDPRESS]', $value);
            $value = str_replace(str_replace('/', '\\', $this->root), '[RAÍZ_WORDPRESS]', $value);
        }
        $value = preg_replace('/\b(?:Authorization|Proxy-Authorization|Cookie|Set-Cookie)\s*:\s*[^\r\n]+/i', '[CABECERA_OCULTA]', (string) $value);
        $value = preg_replace('~\bhttps?://[^\s<]+~i', '[URL_OCULTA]', (string) $value);
        $value = preg_replace('/\b[A-Z0-9._%+\-]+@[A-Z0-9.\-]+\.[A-Z]{2,}\b/i', '[CORREO_OCULTO]', (string) $value);
        $value = preg_replace_callback('/(?<![\d.])(?:\d{1,3}\.){3}\d{1,3}(?![\d.])/', function ($match) {
            return filter_var($match[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false ? '[IP_OCULTA]' : $match[0];
        }, (string) $value);
        $value = preg_replace_callback('/\b(?:[A-F0-9]{0,4}:){2,7}[A-F0-9]{0,4}\b/i', function ($match) {
            return filter_var($match[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false ? '[IP_OCULTA]' : $match[0];
        }, (string) $value);
        $value = preg_replace('~\b[A-Za-z]:[\\\\/](?:[^\\\\/\s]+[\\\\/])+[^\s,;]+~', '[RUTA_OCULTA]', (string) $value);
        $value = preg_replace('~(?<![A-Za-z0-9:])/(?:[A-Za-z0-9._\-]+/)+[A-Za-z0-9._\-]+~', '[RUTA_OCULTA]', (string) $value);
        $value = preg_replace('/\b(?:mysql|mysqli|pdo):[^\s]+/i', '[CONEXIÓN_OCULTA]', (string) $value);
        $value = preg_replace('/(password|passwd|pwd|token|secret|authorization)(\s*[:=]\s*)[^\s,;]+/i', '$1$2[OCULTO]', $value);
        $value = preg_replace('/\b[A-Za-z0-9+\/_=-]{40,}\b/', '[VALOR_LARGO_OCULTO]', (string) $value);
        return trim((string) $value);
    }

    public function data($value)
    {
        if (is_array($value)) {
            $clean = array();
            foreach ($value as $key => $item) {
                $clean[$key] = $this->data($item);
            }
            return $clean;
        }
        return is_string($value) ? $this->text($value) : $value;
    }
}
