<?php

namespace SiipAvailableIps;

/**
 * Validador de IPs usando búsqueda de sitios en UISP
 * Utiliza el endpoint /sites/search para encontrar dispositivos por IP
 */
class IpValidator
{
    private $baseUrl;
    private $apiToken;
    private $logger;

    public function __construct($baseUrl, $apiToken, $logger = null)
    {
        $this->baseUrl = rtrim($baseUrl, '/');
        $this->apiToken = $apiToken;
        $this->logger = $logger;
    }

    /**
     * Verifica si una IP está en uso en UISP usando búsqueda de sitios
     * 
     * @param string $ip IP a verificar
     * @return bool True si la IP está en uso, false si está disponible
     */
    public function isIpInUse($ip)
    {
        try {
            // 1. Buscar sitio por IP usando el endpoint de búsqueda
            // IMPORTANTE: type=subscriber solo busca en sitios de clientes (endpoints)
            $searchUrl = $this->baseUrl . '/nms/api/v2.1/sites/search?query=' . urlencode($ip) . '&count=1&page=1&type=subscriber';
            
            if ($this->logger) {
                $this->logger->appendLog("IpValidator: Buscando sitio para IP $ip");
            }

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $searchUrl);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'X-Auth-Token: ' . $this->apiToken
            ]);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            if ($httpCode !== 200) {
                if ($this->logger) {
                    $this->logger->appendLog("IpValidator: Error HTTP $httpCode al buscar sitio");
                }
                return false; // Si hay error, asumir que no está en uso
            }

            $sites = json_decode($response, true);
            
            // Si no hay sitios, la IP no está en uso
            if (empty($sites) || !isset($sites[0]['id'])) {
                if ($this->logger) {
                    $this->logger->appendLog("IpValidator: No se encontró sitio para IP $ip - DISPONIBLE");
                }
                return false;
            }

            $siteId = $sites[0]['id'];
            
            if ($this->logger) {
                $this->logger->appendLog("IpValidator: Sitio encontrado: $siteId");
            }

            // 2. Obtener dispositivos del sitio
            $devicesUrl = $this->baseUrl . '/nms/api/v2.1/devices?siteId=' . $siteId;
            
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $devicesUrl);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'X-Auth-Token: ' . $this->apiToken
            ]);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            if ($httpCode !== 200) {
                if ($this->logger) {
                    $this->logger->appendLog("IpValidator: Error HTTP $httpCode al obtener dispositivos");
                }
                return false;
            }

            $devices = json_decode($response, true);
            
            // 3. Verificar si algún dispositivo tiene la IP
            foreach ($devices as $device) {
                // Verificar IP principal
                if (isset($device['ipAddress'])) {
                    $deviceIp = explode('/', $device['ipAddress'])[0];
                    if ($deviceIp === $ip) {
                        if ($this->logger) {
                            $this->logger->appendLog("IpValidator: IP $ip encontrada en dispositivo (ipAddress) - EN USO");
                        }
                        return true;
                    }
                }
                
                // Verificar lista de IPs
                if (isset($device['ipAddressList']) && is_array($device['ipAddressList'])) {
                    if (in_array($ip, $device['ipAddressList'])) {
                        if ($this->logger) {
                            $this->logger->appendLog("IpValidator: IP $ip encontrada en dispositivo (ipAddressList) - EN USO");
                        }
                        return true;
                    }
                }
            }

            if ($this->logger) {
                $this->logger->appendLog("IpValidator: IP $ip no encontrada en dispositivos del sitio - DISPONIBLE");
            }
            
            return false;

        } catch (\Exception $e) {
            if ($this->logger) {
                $this->logger->appendLog("IpValidator: Excepción: " . $e->getMessage());
            }
            return false; // En caso de error, asumir disponible
        }
    }

    /**
     * Valida un lote de IPs y devuelve las que están en uso
     * 
     * @param array $ips Array de IPs a validar
     * @return array Array de IPs que están en uso
     */
    public function getIpsInUse(array $ips)
    {
        $ipsInUse = [];
        
        foreach ($ips as $ip) {
            if ($this->isIpInUse($ip)) {
                $ipsInUse[] = $ip;
            }
        }
        
        return $ipsInUse;
    }
}
