<?php
/**
 * affilun Cloud HTTP option helpers.
 *
 * @package Affilun\Application\Cloud
 */

declare(strict_types=1);

namespace Affilun\Application\Cloud;

use RuntimeException;

/**
 * Centralizes WordPress HTTP options for affilun Cloud calls.
 */
final class CloudHttpOptions {

	/**
	 * Return whether TLS certificates should be verified for Cloud calls.
	 *
	 * affilun Cloud always uses the public trusted production certificate.
	 */
	public static function sslVerify(): bool {
		return true;
	}

	/**
	 * Add Cloud-specific WordPress HTTP options.
	 *
	 * affilun Cloud endpoints are allowlisted by {@see CloudSettings}; do not
	 * use WordPress's `reject_unsafe_urls` validation here. In same-host private
	 * alpha deployments, `api.affilun.st` resolves to the LAN/WAN address of the
	 * current host and WordPress rejects that as an unsafe URL before the request
	 * reaches Traefik.
	 *
	 * @param array<string,mixed> $args WordPress HTTP API args.
	 *
	 * @return array<string,mixed>
	 */
	public static function withSslVerify( array $args ): array {
		$args['sslverify']          = self::sslVerify();
		$args['reject_unsafe_urls'] = false;
		if ( ! array_key_exists( 'redirection', $args ) ) {
			$args['redirection'] = 0;
		}
		return $args;
	}

	/**
	 * Execute a Cloud POST request using WordPress's safe HTTP helper when
	 * available.
	 *
	 * @param string              $url  Target URL.
	 * @param array<string,mixed> $args WordPress HTTP API args.
	 *
	 * @return mixed WordPress HTTP response or WP_Error.
	 */
	public static function safePost( string $url, array $args ) {
		self::assertAllowedCloudUrl( $url );
		$args = self::withSslVerify( $args );
		if ( function_exists( 'wp_remote_post' ) ) {
			return wp_remote_post( $url, $args );
		}
		if ( function_exists( 'wp_remote_request' ) ) {
			return wp_remote_request( $url, array_merge( $args, array( 'method' => 'POST' ) ) );
		}
		throw new RuntimeException( 'WordPress HTTP API is unavailable.' );
	}

	/**
	 * Execute a Cloud GET request using WordPress's safe HTTP helper when
	 * available.
	 *
	 * @param string              $url  Target URL.
	 * @param array<string,mixed> $args WordPress HTTP API args.
	 *
	 * @return mixed WordPress HTTP response or WP_Error.
	 */
	public static function safeGet( string $url, array $args ) {
		self::assertAllowedCloudUrl( $url );
		$args = self::withSslVerify( $args );
		if ( function_exists( 'wp_remote_get' ) ) {
			return wp_remote_get( $url, $args );
		}
		if ( function_exists( 'wp_remote_request' ) ) {
			return wp_remote_request( $url, array_merge( $args, array( 'method' => 'GET' ) ) );
		}
		throw new RuntimeException( 'WordPress HTTP API is unavailable.' );
	}

	/**
	 * Ensure Cloud clients only call the production API unless custom endpoints
	 * have been explicitly enabled for development/testing.
	 *
	 * @param string $url Request URL.
	 */
	private static function assertAllowedCloudUrl( string $url ): void {
		if ( self::isProductionCloudUrl( $url ) || self::customEndpointsAllowed() ) {
			return;
		}

		throw new RuntimeException( 'affilun Cloud URL is not allowlisted.' );
	}

	/**
	 * Whether the request targets the canonical production API surface.
	 *
	 * @param string $url Request URL.
	 */
	private static function isProductionCloudUrl( string $url ): bool {
		$parts = wp_parse_url( $url );
		if ( ! is_array( $parts ) ) {
			return false;
		}

		$scheme = strtolower( is_scalar( $parts['scheme'] ?? null ) ? (string) $parts['scheme'] : '' );
		$host   = strtolower( is_scalar( $parts['host'] ?? null ) ? (string) $parts['host'] : '' );
		$path   = is_scalar( $parts['path'] ?? null ) ? (string) $parts['path'] : '';

		return $scheme === 'https'
			&& $host === 'api.affilun.st'
			&& ( $path === '/api/v1' || str_starts_with( $path, '/api/v1/' ) );
	}

	/**
	 * Whether custom Cloud endpoints are explicitly enabled for development.
	 */
	private static function customEndpointsAllowed(): bool {
		$allowed = defined( 'AFFILUN_CLOUD_ALLOW_CUSTOM_ENDPOINTS' ) && (bool) AFFILUN_CLOUD_ALLOW_CUSTOM_ENDPOINTS;
		if ( function_exists( 'apply_filters' ) ) {
			$allowed = (bool) apply_filters( 'affilun_cloud_allow_custom_endpoints', $allowed );
		}
		return $allowed;
	}
}
