<?php
/**
 * Sandbox Manager
 *
 * Manages iframe sandbox configuration based on integration type.
 * Simple, sensible defaults - developers can override if needed.
 *
 * @package FleekDash\Integration
 * @since 2.3.0
 *
 * SECURITY FIX #3: Sandbox Hardening
 * - Type-specific sandbox modes (automatic)
 * - Sensible defaults (security without friction)
 * - Easy to override if needed
 */

namespace FleekDash\Integration;

defined('ABSPATH') || exit;

class SandboxManager
{
    /**
     * Get sandbox configuration for integration type
     *
     * This is called automatically by IntegrationWindowPage.
     * Returns sensible defaults based on type.
     *
     * @param string $integration_type Type (native/standalone/hybrid)
     * @param string $custom_mode Custom sandbox mode (optional override)
     * @return array Sandbox configuration
     */
    public static function getSandboxConfig(string $integration_type, ?string $custom_mode = null): array
    {
        // Allow custom override
        if ($custom_mode && in_array($custom_mode, ['strict', 'moderate', 'none'])) {
            return self::getConfigByMode($custom_mode);
        }

        // Default by type
        switch ($integration_type) {
            case 'native':
                // WordPress native = moderate (needs WP APIs)
                return self::getConfigByMode('moderate');

            case 'standalone':
                // FleekDash-only = strict (isolated)
                return self::getConfigByMode('strict');

            case 'hybrid':
                // Both systems = moderate (flexibility)
                return self::getConfigByMode('moderate');

            default:
                // Unknown = strict (safe default)
                return self::getConfigByMode('strict');
        }
    }

    /**
     * Get configuration by mode
     *
     * @param string $mode Sandbox mode
     * @return array Configuration
     */
    private static function getConfigByMode(string $mode): array
    {
        switch ($mode) {
            case 'strict':
                // Maximum isolation (FleekDash standalone integrations)
                return [
                    'mode' => 'strict',
                    'sandbox_attr' => 'allow-scripts allow-forms',
                    'allow_same_origin' => false,
                    'allow_top_navigation' => false,
                    'allow_popups' => false,
                    'description' => 'Strict isolation (recommended for third-party)',
                ];

            case 'moderate':
                // Balanced (WordPress native plugins)
                return [
                    'mode' => 'moderate',
                    'sandbox_attr' => 'allow-scripts allow-same-origin allow-forms',
                    'allow_same_origin' => true,
                    'allow_top_navigation' => false,
                    'allow_popups' => false,
                    'description' => 'Moderate isolation (WordPress plugins)',
                ];

            case 'none':
                // No sandbox (ONLY for trusted internal integrations)
                return [
                    'mode' => 'none',
                    'sandbox_attr' => '',
                    'allow_same_origin' => true,
                    'allow_top_navigation' => true,
                    'allow_popups' => true,
                    'description' => 'No isolation (trusted only)',
                ];

            default:
                // Fallback to strict
                return self::getConfigByMode('strict');
        }
    }

    /**
     * Get CSP (Content Security Policy) for integration
     *
     * Returns sensible CSP headers based on integration type.
     * Called automatically - transparent to developers.
     *
     * @param string $integration_id Integration ID
     * @return string|null CSP policy or null
     */
    public static function getCSP(string $integration_id): ?string
    {
        global $wpdb;

        $table = $wpdb->prefix . 'fleekdash_integration_routes';

        $csp = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT `csp_policy` FROM `{$table}`
                 WHERE `integration_id` = %s
                 AND `csp_policy` IS NOT NULL
                 LIMIT 1",
                $integration_id
            )
        );

        // If custom CSP, use it
        if ($csp) {
            return $csp;
        }

        // Otherwise, use sensible default
        return self::getDefaultCSP();
    }

    /**
     * Get default CSP policy
     *
     * Sensible default that allows most common use cases.
     *
     * @return string CSP policy
     */
    private static function getDefaultCSP(): string
    {
        return implode('; ', [
            "default-src 'self'",
            "script-src 'self' 'unsafe-inline' 'unsafe-eval'", // Allow inline scripts (needed for many integrations)
            "style-src 'self' 'unsafe-inline'", // Allow inline styles
            "img-src 'self' data: https:", // Allow images from self + data URIs + HTTPS
            "font-src 'self' data:", // Allow fonts
            "connect-src 'self' https:", // Allow AJAX to self + HTTPS
            "frame-ancestors 'self'", // Prevent clickjacking
        ]);
    }

    /**
     * Check if sandbox mode is valid
     *
     * @param string $mode Mode to check
     * @return bool True if valid
     */
    public static function isValidMode(string $mode): bool
    {
        return in_array($mode, ['strict', 'moderate', 'none'], true);
    }

    /**
     * Get recommended mode for integration type
     *
     * @param string $integration_type Integration type
     * @return string Recommended sandbox mode
     */
    public static function getRecommendedMode(string $integration_type): string
    {
        switch ($integration_type) {
            case 'native':
                return 'moderate';
            case 'standalone':
                return 'strict';
            case 'hybrid':
                return 'moderate';
            default:
                return 'strict';
        }
    }
}
