<?php

declare(strict_types=1);

namespace SiteFort\Modules\Firewall\ExtendedProtection;

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

use SiteFort\Modules\Firewall\FirewallConfigService;

if ( ! class_exists( WafRuntimeStore::class, false ) ) {
	require_once __DIR__ . '/WafRuntimeStore.php';
}

final class ConfigCoordinator {
	public static function refresh_if_installed(): void {
		if ( Manager::should_manage_runtime_assets() ) {
			Manager::with_runtime_mutation_lock( static function (): void {
				ConfigWriter::write();
			} );
		}
	}

	public static function ensure_runtime_assets_current(): void {
		if ( ! Manager::should_manage_runtime_assets() ) {
			return;
		}

		Manager::with_runtime_mutation_lock( static function (): void {
			Manager::ensure_bootstrap_current();

			$effective_settings = FirewallConfigService::load_runtime_effective_settings();
			$expected_config    = ConfigWriter::build_config( $effective_settings, true, false );
			$stored_signature_missing = (string) get_option( 'sitefort_waf_policy_signature', '' ) === '';

			if ( $stored_signature_missing || self::config_needs_refresh( $expected_config ) || self::managed_runtime_config_needs_refresh( $expected_config ) ) {
				ConfigWriter::write( $effective_settings );
			}
		} );
	}

	private static function managed_runtime_config_needs_refresh( ?array $expected_config = null ): bool {
		if ( ! Manager::should_use_managed_runtime_storage() ) {
			return false;
		}

		if ( ! is_array( $expected_config ) ) {
			$expected_config = ConfigWriter::build_config( null, true, false );
		}

		$expected_signature = self::config_signature( $expected_config );
		$payload = WafRuntimeStore::get( WafRuntimeStore::KEY_BOOTSTRAP_CONFIG, null );
		if ( ! is_array( $payload ) || (string) ( $payload['runtime_storage_backend'] ?? '' ) !== 'mysqli' ) {
			return true;
		}

		$stored_signature = self::config_signature( $payload );

		return $expected_signature === ''
			|| $stored_signature === ''
			|| ! hash_equals( $expected_signature, $stored_signature );
	}

	public static function config_needs_refresh( ?array $expected_config = null ): bool {
		$config_path = Manager::get_config_path();
		if ( ! is_file( $config_path ) || ! is_readable( $config_path ) ) {
			return true;
		}

		$config = @include $config_path;
		if ( ! is_array( $config ) ) {
			return true;
		}

		$required_files = [
			(string) ( $config['engine_file'] ?? '' ),
			(string) ( $config['search_trust_core_file'] ?? '' ),
			(string) ( $config['search_trust_context_file'] ?? '' ),
			(string) ( $config['search_trust_dns_verifier_file'] ?? '' ),
			(string) ( $config['request_provenance_file'] ?? '' ),
		];

		foreach ( $required_files as $required_file ) {
			if ( $required_file === '' || ! is_file( $required_file ) || ! is_readable( $required_file ) ) {
				return true;
			}
		}

		if ( ! is_array( $expected_config ) ) {
			$expected_config = ConfigWriter::build_config( null, true, false );
		}

		$expected_signature = self::config_signature( $expected_config );
		$stored_signature   = self::config_signature( $config );

		return $expected_signature === ''
			|| $stored_signature === ''
			|| ! hash_equals( $expected_signature, $stored_signature );
	}

	private static function config_signature( array $config ): string {
		return is_string( $config['policy_signature'] ?? null ) ? $config['policy_signature'] : '';
	}
}
