<?php
namespace EasyChat\Library\Support;








final class OfficialSupportNetworkPolicy {
    private const HOST = 'api.easytokens.ru';
    private const PORT = 443;
    private const MAX_IPS = 3;

    private $raw_ips;

    public function __construct(?string $raw_ips = null) {
        $this->raw_ips = $raw_ips === null
            ? OfficialSupportRuntimeConfig::value('EASYCHAT_OFFICIAL_SUPPORT_EDGE_IPS')
            : $raw_ips;
    }

     
    public function curlResolveEntries(): array {
        $raw = trim((string)$this->raw_ips);
        if ($raw === '' || strlen($raw) > 192) {
            return [];
        }

        $values = preg_split('/[\s,]+/', $raw, -1, PREG_SPLIT_NO_EMPTY);
        if (!is_array($values) || !$values || count($values) > self::MAX_IPS) {
            return [];
        }

        $ips = [];
        foreach ($values as $value) {
            $ip = trim((string)$value);
             
             
            if (!$this->isPublicIpv4($ip)) {
                return [];
            }
            if (!in_array($ip, $ips, true)) {
                $ips[] = $ip;
            }
        }

        if (!$ips) {
            return [];
        }

        return [self::HOST . ':' . self::PORT . ':' . implode(',', $ips)];
    }

    private function isPublicIpv4(string $ip): bool {
        if (filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
        ) === false) {
            return false;
        }

        $value = ip2long($ip);
        if ($value === false) {
            return false;
        }
        $value = (int)sprintf('%u', $value);

         
         
         
        foreach ([
            ['0.0.0.0', 8],
            ['10.0.0.0', 8],
            ['100.64.0.0', 10],
            ['127.0.0.0', 8],
            ['169.254.0.0', 16],
            ['172.16.0.0', 12],
            ['192.0.0.0', 24],
            ['192.0.2.0', 24],
            ['192.88.99.0', 24],
            ['192.168.0.0', 16],
            ['198.18.0.0', 15],
            ['198.51.100.0', 24],
            ['203.0.113.0', 24],
            ['224.0.0.0', 4],
            ['240.0.0.0', 4],
        ] as $range) {
            if ($this->inCidr($value, $range[0], $range[1])) {
                return false;
            }
        }

        return true;
    }

    private function inCidr(int $value, string $network, int $prefix): bool {
        $network_value = ip2long($network);
        if ($network_value === false) {
            return true;
        }
        $network_value = (int)sprintf('%u', $network_value);
        $mask = $prefix === 0 ? 0 : ((0xFFFFFFFF << (32 - $prefix)) & 0xFFFFFFFF);
        return ($value & $mask) === ($network_value & $mask);
    }
}
