<?php

class BlocklistGenerator
{
    /**
     * @var string The path to the template file.
     */
    private string $templateFile = __DIR__ . '/template.conf';

    /**
     * @var string The path to the output file.
     */
    private string $outputFile = __DIR__ . '/blocklist.conf';

    /**
     * @var array The blocklist data to be inserted into the template.
     */
    private array $asnList = [];

    /**
     * @var string The base URL for fetching ASN data.
     */
    private string $baseUrl = 'https://asn.ipinfo.app/api/text/nginx';

    /**
     * @var CurlHandle|null The cURL handle for making HTTP requests.
     */
    private ?CurlHandle $curl;

    public function __construct()
    {
        if (!function_exists('curl_init')) {
            throw new Exception("cURL extension is not enabled.");
        }

        $this->curl = curl_init();
    }

    /**
     * Get list of ASNs that have been defined in the template file.
     * 
     * @return array List of ASNs.
     */
    public function getAsnsFromTemplate()
    {
        $templateContent = file_get_contents($this->templateFile);
        preg_match_all('/::(AS\d{1,7})/', $templateContent, $matches);

        $this->asnList = $matches[1];
        return $this->asnList;
    }

    /**
     * Fetch blocklist data for each ASN and generate the final blocklist file.
     */
    public function generateBlocklist()
    {
        $finalBlocklist = file_get_contents($this->templateFile);

        foreach ($this->asnList as $asn) {
            $url = sprintf('%s/%s', $this->baseUrl, $asn);

            curl_setopt($this->curl, CURLOPT_URL, $url);
            curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);

            $response = curl_exec($this->curl);
            if ($response === false) {
                throw new Exception("cURL error: " . curl_error($this->curl));
            }

            $subnetList = explode("\n", trim($response));
            sort($subnetList);

            $result = implode("\n", $subnetList);

            $replaceAsn = sprintf('::%s', $asn);
            $finalBlocklist = str_replace($replaceAsn, $result, $finalBlocklist);
        }

        $timeGenerated = date('c');
        $finalBlocklist = str_replace('TIME_GENERATED', "# Generated on: $timeGenerated", $finalBlocklist);
        file_put_contents($this->outputFile, $finalBlocklist);
    }
}

try {
    $generator = new BlocklistGenerator();
    $generator->getAsnsFromTemplate();
    $generator->generateBlocklist();
    echo "Blocklist generated successfully.\n";
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}