<?php

namespace App\Services;

class ASNService
{
    public static function validateIP($ip, $asn)
    {
        // Remove 'AS' prefix if present for comparison
        $targetAsn = ltrim(strtoupper($asn), 'AS');

        // Use whois command
        // This command queries Cymru's whois server which is reliable for IP to ASN mapping
        // Format: whois -h whois.cymru.com " -v [IP]"

        $command = sprintf('whois -h whois.cymru.com " -v %s"', escapeshellarg($ip));

        // Use proc_open to capture output and potential errors
        $descriptorspec = [
            0 => ["pipe", "r"],  // stdin
            1 => ["pipe", "w"],  // stdout
            2 => ["pipe", "w"]   // stderr
        ];

        $process = proc_open($command, $descriptorspec, $pipes);

        if (is_resource($process)) {
            $output = stream_get_contents($pipes[1]);
            $errors = stream_get_contents($pipes[2]);
            fclose($pipes[0]);
            fclose($pipes[1]);
            fclose($pipes[2]);
            $return_value = proc_close($process);

            if ($return_value !== 0 || empty($output)) {
                // Whois command failed, try HTTP API fallback
                // Using ip-api.com (free, no key required for limited use)
                // Format: http://ip-api.com/json/{ip}?fields=status,message,as

                $apiUrl = "http://ip-api.com/json/" . $ip . "?fields=status,message,as";
                $context = stream_context_create(['http' => ['timeout' => 3]]);
                $apiResponse = @file_get_contents($apiUrl, false, $context);

                if ($apiResponse !== FALSE) {
                    $data = json_decode($apiResponse, true);
                    if (isset($data['status']) && $data['status'] === 'success' && isset($data['as'])) {
                        // Format example: "AS15169 Google LLC"
                        // Extract AS number
                        if (preg_match('/AS(\d+)/', $data['as'], $matches)) {
                            $foundAsn = $matches[1];
                            return $foundAsn === $targetAsn;
                        }
                    }
                }

                // If both fail, strictly return false as requested to prevent invalid registrations
                return false;
            }
        } else {
            return false;
        }

        // Parse output
        // Output example:
        // AS      | IP               | BGP Prefix          | CC | Registry | Allocated  | AS Name
        // 15169   | 8.8.8.8          | 8.8.8.0/24          | US | arin     | 2000-03-30 | GOOGLE, US

        $lines = explode("\n", trim($output));
        foreach ($lines as $line) {
            if (strpos($line, 'AS') !== false && strpos($line, 'IP') !== false) {
                continue;
            }

            $parts = explode('|', $line);
            if (count($parts) >= 1) {
                $foundAsn = trim($parts[0]);
                if ($foundAsn === $targetAsn) {
                    return true;
                }
            }
        }

        return false;
    }

    public static function getPrefixes($asn)
    {
        $asn = ltrim(strtoupper($asn), 'AS');
        $url = "https://stat.ripe.net/data/announced-prefixes/data.json?resource=AS" . $asn;

        $context = stream_context_create(['http' => ['timeout' => 5]]);
        $response = @file_get_contents($url, false, $context);

        if ($response === FALSE) {
            return [];
        }

        $data = json_decode($response, true);
        $prefixes = [];

        if (isset($data['status']) && $data['status'] === 'ok' && isset($data['data']['prefixes'])) {
            foreach ($data['data']['prefixes'] as $item) {
                if (isset($item['prefix'])) {
                    $prefixes[] = $item['prefix'];
                }
            }
        }

        return array_unique($prefixes);
    }
}
