<?php

declare(strict_types=1);

namespace SecurWP\Modules\Firewall\Blocklist;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

use SecurWP\Modules\Cloud\Service\CloudSettings;
use SecurWP\Modules\Cloud\SecureApi;

/**
 * Fetches the compiled threat blocklist from the SecurWP Intel cloud
 * and piggybacks queued crowd-sourced attack reports on the same request.
 *
 * Available to all plans (free, pro, managed). Returns an array of IP
 * addresses and CIDR ranges aggregated from Spamhaus and crowd-sourced
 * network intelligence.
 *
 */
class CloudIntelProvider {

    /**
     * Transient key for caching the blocklist response.
     * The cloud endpoint is rate-limited to once per hour per site, so we
     * cache locally for slightly under that window.
     */
    private const CACHE_TRANSIENT = 'securwp_cloud_intel_blocklist';

    /**
     * Cache TTL in seconds (50 minutes, slightly under the 1h rate limit).
     */
    private const CACHE_TTL = 3000;

    /**
     * Fetch the threat blocklist from the Intel cloud.
     *
     * Reads queued attack reports from ReportBuffer and sends them piggybacked
     * on the blocklist POST request. Reports are only cleared after a
     * successful sync so transient network failures do not silently drop intel.
     * Returns a flat array of IP addresses and CIDR ranges ready to be merged
     * into the blocklist.
     *
     * @return string[]
     */
    public function fetch(): array {
        $settings    = CloudSettings::get_all();
        $site_token  = (string) ( $settings['site_token']  ?? '' );
        $site_secret = (string) ( $settings['site_secret'] ?? '' );
        $license_key = (string) ( $settings['license_key'] ?? '' );

        if ( $site_token === '' || $site_secret === '' ) {
            return [];
        }

        // Return cached result if available.
        $cached = get_transient( self::CACHE_TRANSIENT );
        if ( is_array( $cached ) ) {
            return $cached;
        }

        // Keep queued reports until the cloud sync succeeds.
        $reports = ReportBuffer::peek();
        $body    = ! empty( $reports ) ? [ 'reports' => $reports ] : [];

        $api      = new SecureApi( $license_key, $site_token, $site_secret );
        $response = $api->post( 'services/intelligence/threat-blocklist', $body );

        if ( is_wp_error( $response ) || ! is_array( $response ) ) {
            return [];
        }

        if ( ! empty( $reports ) ) {
            ReportBuffer::clear();
        }

        $ips   = array_values( (array) ( $response['ips']   ?? [] ) );
        $cidrs = array_values( (array) ( $response['cidrs'] ?? [] ) );

        // Filter to valid strings only.
        $entries = array_values( array_filter(
            array_merge( $ips, $cidrs ),
            fn( $e ) => is_string( $e ) && $e !== ''
        ) );

        set_transient( self::CACHE_TRANSIENT, $entries, self::CACHE_TTL );

        return $entries;
    }
}
