<?php

declare(strict_types=1);

namespace SiteFort\Modules\Scanner\Migrations;

use SiteFort\Core\Database\Migration;
use SiteFort\Core\Database\SchemaInspector;
use SiteFort\Includes\RequestVerifier;
use SiteFort\Modules\Scanner\Repository\ScanQueueRepository;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class ScanQueueSchemaV1 implements Migration {

	public function module_key(): string {
		return 'scanner_queue';
	}

	public function target_version(): int {
		return 4;
	}

	public function is_applied(): bool {
		if ( ! $this->has_required_structure() ) {
			return false;
		}

		$tables = $this->tables();
		return SchemaInspector::table_engine_ready( $tables['scan_queue'] )
			&& SchemaInspector::table_engine_ready( $tables['task_queue'] )
			&& RequestVerifier::is_table_schema_current();
	}

	public function apply(): bool {
		if ( ! $this->has_required_structure() ) {
			ScanQueueRepository::ensure_tables();
		} else {
			foreach ( $this->tables() as $table ) {
				SchemaInspector::ensure_table_uses_innodb( $table );
			}
		}

		return RequestVerifier::ensure_table_schema() && $this->is_applied();
	}

	private function has_required_structure(): bool {
		$tables = $this->tables();
		$scan_queue = $tables['scan_queue'];
		$task_queue = $tables['task_queue'];

		if (
			! SchemaInspector::table_exists( $scan_queue ) ||
			! SchemaInspector::table_exists( $task_queue )
		) {
			return false;
		}

		if ( ! SchemaInspector::has_columns(
			$scan_queue,
			[
				'component_status',
				'cloud_error_count',
				'malware_signature_version',
				'next_run_at',
				'last_dispatch_at',
				'task_runner_lease_token',
				'task_runner_lease_until',
				'last_ping',
			]
		) ) {
			return false;
		}

		if ( ! SchemaInspector::has_columns( $task_queue, [ 'lease_until', 'max_attempts', 'dedupe_key' ] ) ) {
			return false;
		}

		return SchemaInspector::has_indexes( $task_queue, [ 'idx_scan_type', 'idx_lease', 'idx_dedupe' ] );
	}

	/**
	 * @return array{scan_queue:string,task_queue:string}
	 */
	private function tables(): array {
		global $wpdb;

		return [
			'scan_queue' => $wpdb->prefix . 'sitefort_scan_queue',
			'task_queue' => $wpdb->prefix . 'sitefort_task_queue',
		];
	}
}
