<?php

use PHPUnit\Framework\TestCase;
use SHServ\Controllers\CronController;
use SHServ\Middleware\ControlScripts;

class TestableCronController extends CronController {
	public $cliCalls = [];
	public $returnCodes = [];
	protected function run_script_cli(String $alias): int {
		$this -> cliCalls[] = $alias;
		return $this -> returnCodes[$alias] ?? 0;
	}
}

class CronControllerTest extends TestCase {
	protected $tb;

	protected function setUp(): void {
		$this -> tb = app() -> thin_builder;
		$this -> tb -> query("CREATE TABLE scripts (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			area_id INTEGER DEFAULT 0,
			uniq_name TEXT,
			type TEXT,
			state TEXT,
			create_at TEXT,
			update_at TEXT
		)");
		ControlScripts::flush_statics();
	}

	protected function tearDown(): void {
		$this -> tb -> query("DROP TABLE IF EXISTS scripts");
		ControlScripts::flush_statics();
	}

	public function test_regular_scripts_are_dispatched_to_cli(): void {
		$ref = new \ReflectionClass(ControlScripts::class);
		$prop = $ref -> getProperty('regular_scripts');
		$prop -> setAccessible(true);

		$scripts = [
			'fail_script' => [
				'attributes' => ['alias' => 'fail_script', 'name' => 'Fail'],
				'code' => '',
				'script' => function() {}
			],
			'ok_script' => [
				'attributes' => ['alias' => 'ok_script', 'name' => 'OK'],
				'code' => '',
				'script' => function() {}
			]
		];
		$prop -> setValue(null, $scripts);

		$this -> tb -> insert('scripts', [
			'uniq_name' => 'fail_script',
			'type' => 'regular',
			'state' => 'enabled',
			'create_at' => date('Y-m-d H:i:s'),
		]);
		$this -> tb -> insert('scripts', [
			'uniq_name' => 'ok_script',
			'type' => 'regular',
			'state' => 'enabled',
			'create_at' => date('Y-m-d H:i:s'),
		]);

		$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
		$controller = new TestableCronController();
		$controller -> returnCodes = ['fail_script' => 1, 'ok_script' => 0];
		$controller -> run_regular_cron_scripts();

		$this -> assertSame(['fail_script', 'ok_script'], $controller -> cliCalls);
	}

	public function test_disabled_regular_scripts_are_skipped(): void {
		$ref = new \ReflectionClass(ControlScripts::class);
		$prop = $ref -> getProperty('regular_scripts');
		$prop -> setAccessible(true);

		$scripts = [
			'disabled_script' => [
				'attributes' => ['alias' => 'disabled_script', 'name' => 'Disabled'],
				'code' => '',
				'script' => function() {}
			]
		];
		$prop -> setValue(null, $scripts);

		$this -> tb -> insert('scripts', [
			'uniq_name' => 'disabled_script',
			'type' => 'regular',
			'state' => 'disabled',
			'create_at' => date('Y-m-d H:i:s'),
		]);

		$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
		$controller = new TestableCronController();
		$controller -> run_regular_cron_scripts();

		$this -> assertSame([], $controller -> cliCalls);
	}
}
