<?php

declare( strict_types=1 );

namespace Simplyin\Simplyin_W_Plugin\Tests\Unit;

use Brain\Monkey;
use Brain\Monkey\Functions;
use PHPUnit\Framework\TestCase;
use Simplyin\Simplyin_W_Plugin\Plugin;

/**
 * Regression: Plugin::schedule_rsa_auto_register() unconditionally called spawn_cron() right
 * after scheduling the one-off RSA auto-registration event. Under WP-CLI (e.g. any `wp` command
 * run right after a version bump, while a shop has API-connection saved but RSA not yet
 * registered — the exact state of the schedule/plugins_loaded migration path), this crashed with
 * "Undefined constant WP_CRON_LOCK_TIMEOUT" deep inside WordPress core's spawn_cron(), even
 * though the constant is defined unconditionally and early in wp-settings.php — a WP-CLI
 * bootstrap-order quirk, not something spawn_cron() needs to attempt under WP-CLI anyway (its
 * wp-cron.php loopback ping is meaningless outside a real front-end request).
 *
 * These tests exercise schedule_rsa_auto_register() directly with RSA not yet registered
 * (the only branch that reaches spawn_cron()) and assert it is skipped under WP_CLI, still
 * called otherwise.
 */
final class Schedule_Rsa_Auto_Register_Cli_Guard_Test extends TestCase {

	protected function setUp(): void {
		parent::setUp();
		Monkey\setUp();

		Functions\when( 'get_option' )->alias(
			static function ( $name, $default = false ) {
				if ( 'SimplyInApiConnection' === $name ) {
					return '1';
				}
				// Everything else (RSA private key, credential id, disabled flag) empty/unset:
				// RSA not registered, not disabled — the only state that reaches spawn_cron().
				return $default;
			}
		);
		Functions\when( 'wp_next_scheduled' )->justReturn( false );
	}

	protected function tearDown(): void {
		Monkey\tearDown();
		parent::tearDown();
	}

	public function test_spawn_cron_is_called_when_not_under_wp_cli(): void {
		Functions\expect( 'wp_schedule_single_event' )->once()->andReturn( true );
		Functions\expect( 'spawn_cron' )->once();

		Plugin::schedule_rsa_auto_register();

		$this->addToAssertionCount( 1 );
	}

	/**
	 * @runInSeparateProcess
	 * @preserveGlobalState disabled
	 */
	public function test_spawn_cron_is_skipped_under_wp_cli(): void {
		define( 'WP_CLI', true );

		// The event itself must still be queued under WP-CLI — only spawn_cron()'s loopback
		// ping is skipped. Asserted explicitly (Copilot finding) so a future "fix" that
		// early-returns entirely under WP-CLI — silently dropping the scheduled event too —
		// fails this test.
		Functions\expect( 'wp_schedule_single_event' )->once()->andReturn( true );
		Functions\expect( 'spawn_cron' )->never();

		Plugin::schedule_rsa_auto_register();

		$this->addToAssertionCount( 1 );
	}
}
