<?php
/**
 * MikroTik RouterOS REST API Client
 * Compatível com RouterOS 7.x (REST API nativa)
 */

class MikrotikApi {
    private string $baseUrl;
    private string $user;
    private string $pass;
    private int    $timeout;

    public function __construct(array $device, int $timeout = 8) {
        $scheme = $device['api_use_ssl'] ? 'https' : 'http';
        $port   = $device['api_port'] ?? 80;
        $this->baseUrl = "{$scheme}://{$device['hostname']}:{$port}/rest";
        $this->user    = $device['api_user'] ?? 'admin';
        $this->pass    = $device['api_password'] ?? '';
        $this->timeout = $timeout;
    }

    /**
     * Faz uma requisição GET para a API
     */
    public function get(string $endpoint, array $query = []): ?array {
        $url = $this->baseUrl . $endpoint;
        if (!empty($query)) {
            $url .= '?' . http_build_query($query);
        }
        return $this->request('GET', $url);
    }

    /**
     * Faz uma requisição POST para a API
     */
    public function post(string $endpoint, array $body = []): ?array {
        return $this->request('POST', $this->baseUrl . $endpoint, $body);
    }

    private function request(string $method, string $url, array $body = []): ?array {
        if (!function_exists('curl_init')) return null;

        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL            => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => $this->timeout,
            CURLOPT_USERPWD        => $this->user . ':' . $this->pass,
            CURLOPT_HTTPAUTH       => CURLAUTH_BASIC,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_HTTPHEADER     => ['Content-Type: application/json', 'Accept: application/json'],
        ]);

        if ($method === 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            if (!empty($body)) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
            }
        }

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

        if ($response === false || $httpCode < 200 || $httpCode >= 300) {
            return null;
        }

        return json_decode($response, true);
    }

    /**
     * Retorna recursos do sistema (CPU, RAM, uptime)
     */
    public function getSystemResource(): ?array {
        return $this->get('/system/resource');
    }

    /**
     * Retorna lista de interfaces
     */
    public function getInterfaces(): ?array {
        return $this->get('/interface');
    }

    /**
     * Retorna clientes PPPoE ativos
     */
    public function getPppoeActive(): ?array {
        return $this->get('/interface/pppoe-server/active');
    }

    /**
     * Retorna leases DHCP ativos
     */
    public function getDhcpLeases(): ?array {
        return $this->get('/ip/dhcp-server/lease');
    }

    /**
     * Retorna endereços IP das interfaces
     */
    public function getIpAddresses(): ?array {
        return $this->get('/ip/address');
    }

    /**
     * Testa conexão com o dispositivo
     */
    public function testConnection(): bool {
        return $this->getSystemResource() !== null;
    }

    /**
     * Converte uptime MikroTik (ex: "5d22h34m12s") → segundos
     */
    public static function uptimeToSeconds(string $uptime): int {
        $secs = 0;
        if (preg_match('/(\d+)w/', $uptime, $m)) $secs += (int)$m[1] * 604800;
        if (preg_match('/(\d+)d/', $uptime, $m)) $secs += (int)$m[1] * 86400;
        if (preg_match('/(\d+)h/', $uptime, $m)) $secs += (int)$m[1] * 3600;
        if (preg_match('/(\d+)m/', $uptime, $m)) $secs += (int)$m[1] * 60;
        if (preg_match('/(\d+)s/', $uptime, $m)) $secs += (int)$m[1];
        return $secs;
    }

    /**
     * Parse de memória MikroTik (ex: "64.0MiB" → bytes)
     */
    public static function parseMemory(string $val): int {
        $val = strtolower(trim($val));
        if (str_ends_with($val, 'gib')) return (int)(floatval($val) * 1073741824);
        if (str_ends_with($val, 'mib')) return (int)(floatval($val) * 1048576);
        if (str_ends_with($val, 'kib')) return (int)(floatval($val) * 1024);
        if (str_ends_with($val, 'gb')) return (int)(floatval($val) * 1000000000);
        if (str_ends_with($val, 'mb')) return (int)(floatval($val) * 1000000);
        if (str_ends_with($val, 'kb')) return (int)(floatval($val) * 1000);
        return (int)$val;
    }
}
