<?php

/**
 * Execution time helper.
 *
 * @package northmill-online-shared
 */
declare (strict_types=1);
namespace Northmill_Online_Shared_Sync\Northmill_Online_Shared\Helpers;

/**
 * Execution time class.
 */
class Execution_Time
{
    /**
     * Start time.
     *
     * @var float
     */
    private float $start_time;
    /**
     * End time.
     *
     * @var float
     */
    private float $end_time;
    /**
     * Start time in resource usage format.
     *
     * @var array
     */
    private array $start_time_ru;
    /**
     * End time in resource usage format.
     *
     * @var array
     */
    private array $end_time_ru;
    /**
     * Start the timer.
     */
    public function start(): void
    {
        $this->start_time_ru = getrusage();
        $this->start_time = microtime(\true);
    }
    /**
     * Stop the timer.
     */
    public function end(): void
    {
        $this->end_time_ru = getrusage();
        $this->end_time = microtime(\true);
    }
    /**
     * Get elapsed user or system time.
     *
     * @param array  $ru Resource usage array.
     * @param array  $rus Resource usage start array.
     * @param string $index Index to get.
     */
    private function run_time($ru, $rus, $index): float|int
    {
        return $ru["ru_{$index}.tv_sec"] * 1000 + intval($ru["ru_{$index}.tv_usec"] / 1000) - ($rus["ru_{$index}.tv_sec"] * 1000 + intval($rus["ru_{$index}.tv_usec"] / 1000));
    }
    /**
     * Get elapsed user and system time as a string.
     */
    public function ru_to_string(): string
    {
        return 'This process used ' . $this->run_time($this->end_time_ru, $this->start_time_ru, 'utime') . " ms for its computations\nIt spent " . $this->run_time($this->end_time_ru, $this->start_time_ru, 'stime') . " ms in system calls\n";
    }
    /**
     * Get elapsed wall time.
     */
    public function get_time(): ?float
    {
        if (!isset($this->start_time) || !isset($this->end_time)) {
            return null;
        }
        return $this->end_time - $this->start_time;
    }
    /**
     * Get elapsed wall time as a string.
     */
    public function time_to_string(): string
    {
        $time = $this->get_time();
        if (is_null($time)) {
            if (!isset($this->start_time)) {
                return __('Timer not started', 'northmill-online-shared');
            } else {
                return __('Timer not stopped', 'northmill-online-shared');
            }
        } elseif ($time < 1) {
            $ms_time = round($time * 1000, 2);
            return sprintf(
                // translators: %s is the time in milliseconds.
                __('This process took %s ms', 'northmill-online-shared'),
                $ms_time
            );
        } elseif ($time < 120) {
            return sprintf(
                // translators: %s is the time in seconds.
                __('This process took %s seconds', 'northmill-online-shared'),
                round($time, 2)
            );
        } else {
            $time_minutes = (int) round($time / 60);
            return Time_Helpers::get_duration_label($time_minutes);
        }
    }
}
