<?php
/**
 * Resource Manager - Memory Control
 *
 * Ensures the application has sufficient resources for intensive image processing.
 *
 * @package PackshotPhotoAI
 */

namespace PackshotPhotoAI\Core;

defined('ABSPATH') || exit;

/**
 * Manages PHP resources like memory limit and execution time.
 */
class MemoryManager {

    /**
     * Minimum recommended memory for standard operations
     */
    private const MIN_MEM_STANDARD = '128M';

    /**
     * Recommended memory for bulk/intensive operations
     */
    private const MIN_MEM_INTENSIVE = '512M';

    /**
     * Try to increase memory limit if it's below a certain threshold.
     *
     * @param bool $intensive Whether the task is memory-intensive (e.g. Bulk processing)
     */
    public static function ensure_memory_limit(bool $intensive = false): void {
        $current_limit = self::get_memory_limit();
        $target        = $intensive ? self::MIN_MEM_INTENSIVE : self::MIN_MEM_STANDARD;

        // Convert current limit to bytes for comparison
        $current_bytes = self::let_to_bytes($current_limit);
        $target_bytes  = self::let_to_bytes($target);

        // If we are already above or equal to target, do nothing
        if ($current_bytes >= $target_bytes) {
            return;
        }

        // Try to increase using WP native function if possible (handles multi-site etc)
        if (function_exists('wp_raise_memory_limit')) {
            wp_raise_memory_limit($intensive ? 'admin' : 'image');
        }

        // Additional attempt via ini_set (fails on some hosts but worth trying)
        $new_limit = $intensive ? '512M' : '256M';
        // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged
        @ini_set('memory_limit', $new_limit);

        $limit_after = self::get_memory_limit();
        Logger::debug('Memory: Attempted upgrade', [
            'before' => $current_limit,
            'after'  => $limit_after,
            'target' => $target
        ]);
    }

    /**
     * Try to increase execution time for long processes
     *
     * @param int $seconds
     */
    public static function ensure_time_limit(int $seconds = 300): void {
        if (!function_exists('set_time_limit')) return;

        $current = ini_get('max_execution_time');
        if ($current > 0 && $current < $seconds) {
            // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged
            @set_time_limit($seconds);
            Logger::debug('Time: Increased limit', ['before' => $current, 'after' => $seconds]);
        }
    }

    /**
     * Get current memory limit string
     */
    public static function get_memory_limit(): string {
        $limit = ini_get('memory_limit');
        return $limit ? $limit : '-1';
    }

    /**
     * Convert shorthand shorthand memory notation (eg. 128M) to bytes.
     *
     * @param string $val
     * @return int Bytes
     */
    public static function let_to_bytes(string $val): int {
        $val  = trim($val);
        $last = strtolower($val[strlen($val) - 1]);
        $val  = (int) $val;

        switch ($last) {
            case 'g':
                $val *= 1024;
            case 'm':
                $val *= 1024;
            case 'k':
                $val *= 1024;
        }

        return $val;
    }
}
