<?php

namespace Limb_Chatbot\Includes\Services\Jobs\Managers;

/**
 * Job Processing Limits Manager
 *
 * Handles time and memory limit checking during job processing.
 * Prevents timeouts and memory exhaustion.
 *
 * @since 1.1.0
 */
class Job_Processing_Limits {

	/**
	 * Default time limit for batch processing in seconds.
	 *
	 * @var int
	 * @since 1.1.0
	 */
	private int $time_limit = 20;

	/**
	 * Memory limit percentage to respect (0.9 = 90%).
	 *
	 * @var float
	 * @since 1.1.0
	 */
	private float $memory_limit_percentage = 0.9;

	/**
	 * Start time of current processing batch.
	 *
	 * @var int
	 * @since 1.1.0
	 */
	private int $start_time = 0;

	/**
	 * Constructor.
	 *
	 * @param  int  $time_limit  Time limit in seconds.
	 * @param  float  $memory_limit_percentage  Memory limit percentage (0.0-1.0).
	 *
	 * @since 1.1.0
	 */
	public function __construct( int $time_limit = 20, float $memory_limit_percentage = 0.9 ) {
		$this->time_limit            = $time_limit;
		$this->memory_limit_percentage = $memory_limit_percentage;
	}

	/**
	 * Start tracking processing limits.
	 *
	 * Call this at the beginning of batch processing.
	 *
	 * @return void
	 * @since 1.1.0
	 */
	public function start(): void {
		$this->start_time = time();
	}

	/**
	 * Check if time limit has been exceeded.
	 *
	 * @return bool True if time limit exceeded.
	 * @since 1.1.0
	 */
	public function time_exceeded(): bool {
		if ( $this->start_time === 0 ) {
			return false;
		}

		$finish = $this->start_time + $this->time_limit;

		return time() >= $finish;
	}

	/**
	 * Check if memory limit has been exceeded.
	 *
	 * @return bool True if memory limit exceeded.
	 * @since 1.1.0
	 */
	public function memory_exceeded(): bool {
		$memory_limit   = $this->get_memory_limit() * $this->memory_limit_percentage;
		$current_memory = memory_get_usage( true );

		return $current_memory >= $memory_limit;
	}

	/**
	 * Check if any limit has been exceeded.
	 *
	 * @return bool True if any limit exceeded.
	 * @since 1.1.0
	 */
	public function exceeded(): bool {
		return $this->time_exceeded() || $this->memory_exceeded();
	}

	/**
	 * Get memory limit in bytes.
	 *
	 * @return int Memory limit in bytes.
	 * @since 1.1.0
	 */
	private function get_memory_limit(): int {
		if ( function_exists( 'ini_get' ) ) {
			$memory_limit = ini_get( 'memory_limit' );
		} else {
			// Sensible default
			$memory_limit = '128M';
		}

		if ( ! $memory_limit || -1 === intval( $memory_limit ) ) {
			// Unlimited, set to 32GB
			$memory_limit = '32000M';
		}

		return wp_convert_hr_to_bytes( $memory_limit );
	}
}
