<?php
/**
 *       @file  qtrAjaxTimerGuard.php
 *      @brief  AJAX request timing guard using RAII (Resource Acquisition Is Initialization) pattern
 *
 *     @author  Quttera (qtr), contactus@quttera.com
 *
 *   @internal
 *     Created  04/25/2026
 *     Company  Quttera
 *   Copyright  Copyright (c) 2026, Quttera
 *
 * This source code is released for free distribution under the terms of the
 * GNU General Public License as published by the Free Software Foundation.
 * =====================================================================================
 * 
 * USAGE:
 * ------
 * Simply create an instance at the start of any function:
 *     $timer = new CQtrAjaxTimerGuard(__FUNCTION__);
 * 
 * The destructor will automatically log execution time when the function exits,
 * including early returns and exceptions. No manual logging needed!
 * 
 * Example:
 *     public static function GetStats()
 *     {
 *         $timer = new CQtrAjaxTimerGuard(__FUNCTION__);
 *         
 *         // ... function logic ...
 *         wp_send_json_success($data);  // No need to log - destructor handles it
 *     }
 */

require_once('qtrLogger.php');

class CQtrAjaxTimerGuard
{
    private $_start_time;
    private $_action_name;
    private $_logger;
    private $_is_error = false;

    /**
     * @brief Constructor - starts timer on guard creation
     * @details Captures the start time and logger instance when guard object is instantiated.
     *          This is called at function entry point.
     * 
     * @param string $action_name - Name of AJAX action being timed (typically __FUNCTION__)
     */
    public function __construct($action_name = 'unknown')
    {
        $this->_action_name = $action_name;
        $this->_start_time = microtime(true);
        $this->_logger = new CQtrLogger();
        $this->_logger->Debug("AJAX: Starting handler [{$this->_action_name}]");
    }

    /**
     * @brief Mark this request as errored for status tracking
     * @details Call this before wp_send_json_error() to mark the request as failed.
     *          The destructor will log "error" status instead of "success".
     * @return void
     */
    public function MarkError()
    {
        $this->_is_error = true;
    }

    /**
     * @brief Destructor - logs timing when guard object is destroyed
     * @details Automatically called when:
     *          - Function returns normally (explicit return or end of function)
     *          - Early return statements
     *          - Function throws an exception
     *          - Function exits via exit() or die()
     * 
     *          This guarantees logging on all exit paths without manual intervention.
     */
    public function __destruct()
    {
        $elapsed_ms = round((microtime(true) - $this->_start_time) * 1000, 2);
        $status = $this->_is_error ? 'error' : 'success';
        $this->_logger->Info("AJAX [{$status}]: {$this->_action_name} - {$elapsed_ms}ms");
    }
}
?>
