<?php if (!defined('ABSPATH'))
	exit; ?>
<?php

class polylai_Cron
{
	const LOCK_TRANSIENT_KEY = "polylai_running";
	const REAL_CRON_TRANSIENT_KEY = "polylai_real_cron";
	private $cli = false;
	private $translator;

	private static $instance;

	// implement singleton pattern
	public static function getInstance()
	{
		if (self::$instance == null) {
			$c = __CLASS__;
			self::$instance = new $c;
		}

		return self::$instance;
	}

	public function __construct()
	{
		try {
			ignore_user_abort(true);
		} catch (Exception $e) {
			polylai_Utils::db_log('error', 'ignore_user_abort', $e->getMessage());
		}

		$ai_engine = polylai_Utils::get_ai_engine();
		$this->translator = new polylai_Translator($ai_engine);

		if (isset($_SERVER['argv']) && is_array($_SERVER['argv']) && count($_SERVER['argv'])) {
			polylai_Utils::db_log('debug', 'cron', "cron cli request $ai_engine");
			foreach ($_SERVER['argv'] as $arg) {
				$e = explode('=', sanitize_text_field($arg));
				if ($e[0] === 'polylai_cron') {
					$this->cli = true;

					add_action('wp_loaded', [$this, 'execCron'], 1);
				}

				if ($e[0] === 'polylai_reset') {
					delete_transient(self::LOCK_TRANSIENT_KEY);
				}
			}
		}

		// Request from crontab, cannot use wp_nonce
		if (isset($_GET['action']) && sanitize_text_field($_GET['action']) == 'polylai_run_cron') {
			polylai_Utils::db_log('info', 'cron', "cron http request $ai_engine");
			add_action('wp_loaded', [$this, 'execCron'], 1);
		}
	}


	public function execCron($exit = true)
	{
		polylai_Utils::db_log('debug', 'cron', 'exec cron');
		if ($this->cli) {
			set_transient(self::REAL_CRON_TRANSIENT_KEY, gmdate('Y-m-d H:i:s'), 70);
		}
		$this->fetch_posts();
		polylai_Utils::db_log('debug', 'cron', 'exec cron completed');

		if ($exit) {
			die();
		}
	}

	public function check_for_posts()
	{
		polylai_Utils::db_log('debug', 'cron', 'check_for_posts');

		$results = polylai_Manager::getInstance()->list_pending('local');
		return count($results) > 0;
	}

	public function fetch_posts()
	{
		polylai_Utils::db_log('debug', 'cron', 'fetch_posts');

		if (!$this->check_for_posts()) {
			polylai_Utils::db_log('debug', 'cron', 'no posts');
			delete_transient(self::LOCK_TRANSIENT_KEY);
			return;
		}

		$running = get_transient(self::LOCK_TRANSIENT_KEY);
		if ($running) {
			polylai_Utils::db_log('debug', 'cron', 'already running, exiting');
			return false;
		}

		set_transient(self::LOCK_TRANSIENT_KEY, '1');

		$results = polylai_Manager::getInstance()->list_pending('local');

		if (count($results) == 0) {
			delete_transient(self::LOCK_TRANSIENT_KEY);
			polylai_Utils::db_log('debug', 'cron', "0 posts to translate");
			return;
		}

		$allowed = polylai_Utils::allowed_langs();

		polylai_Utils::db_log('debug', 'cron', count($results) . " results");

		foreach ($results as $key => $row) {
			$id = $row->source_post_id;
			if (!in_array($row->locale_to, $allowed)) {
				continue;
			}

			polylai_Utils::db_log('info', 'cron', "processing $row->locale_to", $row->source_post_id);
			polylai_Manager::getInstance()->set_translating($row->id);
			$this->translator->translate($row->source_post_id, $row->locale_to, $row->lang_to, $row->final_post_status);
			polylai_Manager::getInstance()->set_completed($row->id);

			// we translate only one post at time for avoiding the process to be
			// too long and maybe killed by the web server
			break;
		}

		polylai_Utils::db_log('info', 'cron', 'complete');
		delete_transient(self::LOCK_TRANSIENT_KEY);
		wp_die();
	}
}