<?php
/**
 * WP-Cron scan runner.
 *
 * @package LocalGuardScanner
 */

namespace LocalGuardScanner\Infrastructure\WordPress;

use LocalGuardScanner\Application\Scan\ScanFailure;
use LocalGuardScanner\Application\Scan\ScanOrchestrator;
use Throwable;

/**
 * Starts daily scans and advances one bounded continuation slice.
 */
final class CronScanRunner {
	/** @var ScanOrchestrator */
	private $orchestrator;
	/** @var Settings */
	private $settings;

	/**
	 * @param ScanOrchestrator $orchestrator Orchestrator.
	 * @param Settings         $settings     Settings.
	 */
	public function __construct( ScanOrchestrator $orchestrator, Settings $settings ) {
		$this->orchestrator = $orchestrator;
		$this->settings     = $settings;
	}

	/** @return void */
	public function register() {
		add_action( CronScheduler::DAILY_HOOK, array( $this, 'daily' ) );
		add_action( CronScheduler::CONTINUE_HOOK, array( $this, 'continue_scan' ) );
	}

	/** @return void */
	public function daily() {
		$settings = $this->settings->all();
		if ( empty( $settings['daily_enabled'] ) ) {
			return;
		}
		try {
			$scan_id = $this->orchestrator->start( 'automatic' );
			$this->orchestrator->run_slice( $scan_id );
			delete_site_option( 'lgs_last_cron_error' );
		} catch ( Throwable $error ) {
			update_site_option(
				'lgs_last_cron_error',
				array(
					'time'  => time(),
					'stage' => 'daily',
					'code'  => $error instanceof ScanFailure ? $error->failure_code() : 'LGS-UNEXPECTED',
				)
			);
			return;
		}
	}

	/** @return void */
	public function continue_scan() {
		$active = $this->orchestrator->scans()->active();
		if ( null === $active ) {
			return;
		}
		try {
			$this->orchestrator->run_slice( (int) $active['id'] );
			delete_site_option( 'lgs_last_cron_error' );
		} catch ( Throwable $error ) {
			update_site_option(
				'lgs_last_cron_error',
				array(
					'time'  => time(),
					'stage' => 'continuation',
					'code'  => $error instanceof ScanFailure ? $error->failure_code() : 'LGS-UNEXPECTED',
				)
			);
			return;
		}
	}
}
