<?php
/**
 * Small runtime utility helpers for admin autonomy.
 *
 * @package Niwa_AI
 */

defined( 'ABSPATH' ) || exit;

class Niwa_AI_Admin_Autonomy_Runtime_Utils {
	/** @var array<string,callable> */
	private $callbacks;

	public function __construct( $callbacks = array() ) {
		$this->callbacks = is_array( $callbacks ) ? $callbacks : array();
	}

	public function get_runner_liveness_ttl() {
		return intval( $this->call( 'turn_worker_time_limit', array(), 0 ) ) + 120;
	}

	public function raise_loopback_runner_runtime_limit() {
		$before = function_exists( 'ini_get' ) ? (string) ini_get( 'max_execution_time' ) : '';
		$target = intval( $this->call( 'turn_worker_time_limit', array(), 0 ) );

		if ( $target > 0 && function_exists( 'ini_set' ) ) {
			@ini_set( 'max_execution_time', (string) $target );
		}
		if ( $target > 0 && function_exists( 'set_time_limit' ) ) {
			@set_time_limit( $target );
		}

		$after = function_exists( 'ini_get' ) ? (string) ini_get( 'max_execution_time' ) : '';
		$this->call(
			'debug_logger',
			array(
				'loopback_runner_runtime_limit_timeout_budget',
				array(
					'target_seconds'             => $target,
					'max_execution_time_before'  => $before,
					'max_execution_time_after'   => $after,
					'ini_set_available'          => function_exists( 'ini_set' ),
					'set_time_limit_available'   => function_exists( 'set_time_limit' ),
					'sapi'                       => function_exists( 'php_sapi_name' ) ? php_sapi_name() : '',
				),
			)
		);
	}

	public function format_exception_message( Throwable $e ) {
		error_log(
			'[Niwa AI Admin Runtime] ' . $e->getMessage()
			. ' in ' . basename( str_replace( '\\', '/', (string) $e->getFile() ) )
			. ':' . intval( $e->getLine() )
		);
		return '';
	}

	public function acknowledge_async_request( $body = 'ok' ) {
		if ( headers_sent() ) {
			return;
		}

		$body = (string) $body;

		status_header( 200 );
		nocache_headers();
		header( 'Content-Type: text/plain; charset=utf-8' );
		header( 'Connection: close' );
		header( 'Content-Length: ' . strlen( $body ) );

		echo $body;

		while ( ob_get_level() > 0 ) {
			@ob_end_flush();
		}

		flush();

		if ( function_exists( 'fastcgi_finish_request' ) ) {
			fastcgi_finish_request();
		}
	}

	public function text_length( $text ) {
		return function_exists( 'mb_strlen' ) ? mb_strlen( (string) $text, 'UTF-8' ) : strlen( (string) $text );
	}

	public function text_substr( $text, $start, $length = null ) {
		if ( function_exists( 'mb_substr' ) ) {
			return null === $length
				? mb_substr( (string) $text, intval( $start ), null, 'UTF-8' )
				: mb_substr( (string) $text, intval( $start ), intval( $length ), 'UTF-8' );
		}

		return null === $length
			? substr( (string) $text, intval( $start ) )
			: substr( (string) $text, intval( $start ), intval( $length ) );
	}

	public function truncate_text( $text, $max = 90 ) {
		$text = trim( wp_strip_all_tags( (string) $text ) );
		$max  = max( 3, intval( $max ) );
		if ( strlen( $text ) <= $max ) {
			return $text;
		}

		return substr( $text, 0, $max - 3 ) . '...';
	}

	public function format_timestamp( $timestamp ) {
		$timestamp = intval( $timestamp );
		if ( $timestamp <= 0 ) {
			return '-';
		}

		return wp_date( 'Y-m-d H:i:s', $timestamp );
	}

	private function call( $name, $args = array(), $default = null ) {
		return Niwa_AI_Admin_Autonomy_Callbacks::call( $this->callbacks, $name, $args, $default );
	}
}
