<?php

declare(strict_types=1);

/**
 * ScanTypes - Defines scan type configurations.
 *
 * Standard: Scans wp-admin, wp-includes, wp-content (all contents) and flat
 *           files in the WordPress root. Non-WP subdirectories directly under
 *           ABSPATH (e.g. phpmyadmin/, backup/) are excluded.
 *           Code files only. Safe hash cache is trusted.
 *
 * Deep:     Same coverage as standard plus non-WP ABSPATH root directories.
 *           Images and documents are collected for local binary pre-filtering
 *           before cloud escalation. Safe hash cache is bypassed for fresh verdicts.
 *
 */

namespace SecurWP\Modules\Scanner;

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

class ScanTypes {

	const STANDARD = 'standard';
	const DEEP     = 'deep';

	// File extension groups.
	const CODE_EXTENSIONS     = [ 'php', 'phtml', 'php5', 'php7', 'php8', 'js', 'html', 'htm', 'htaccess', 'ini', 'xml', 'css', 'txt', 'shtml' ];
	const IMAGE_EXTENSIONS    = [ 'jpg', 'jpeg', 'png', 'gif', 'ico', 'svg', 'webp' ];
	const DOCUMENT_EXTENSIONS = [ 'pdf', 'doc', 'docx' ];

	// Shared file size cap across all scan types.
	const MAX_FILE_SIZE = 8 * 1024 * 1024; // 8 MB

	/**
	 * Get configuration for a scan type.
	 *
	 * @param string $type Scan type constant (standard|deep).
	 * @return array<string, mixed>
	 */
	public static function get_config( string $type ): array {
		$configs = [
			self::STANDARD => [
				'name'        => 'Standard Scan',
				'description' => 'Fast integrity check with targeted malware scanning',

				// Standard mode skips non-WP subdirectories directly under ABSPATH
				// (e.g. phpmyadmin/, backup/). Everything inside wp-admin, wp-includes,
				// and wp-content is always scanned.
				'scan_root_extras' => false,

				// Safe hash cache is trusted (credit-efficient for daily scans).
				// Verified verdicts are always trusted in both modes.
				'bypass_safe_cache' => false,

				// Images and documents are not collected in standard mode.
				'binary_check_images' => false,

				// Code file extensions only.
				'extensions'    => self::CODE_EXTENSIONS,
				'max_file_size' => self::MAX_FILE_SIZE,

				'integrity_check'     => true,
				'vulnerability_check' => true,
				'estimated_time'      => '1-3 minutes',
			],

			self::DEEP => [
				'name'        => 'Deep Scan',
				'description' => 'Full scan including non-WP directories; images validated and pre-filtered locally before cloud escalation',

				// Deep mode also scans non-WP subdirectories under ABSPATH.
				'scan_root_extras' => true,

				// Safe cache bypassed: all files get a fresh cloud verdict.
				// Verified verdicts are still trusted (cryptographic proof against WP.org repo).
				'bypass_safe_cache' => true,

				// Images and documents are collected. Image type validation and a fast
				// local binary content check run first; only suspicious files are escalated.
				'binary_check_images' => true,

				// Code + image + document extensions.
				'extensions'    => array_merge(
					self::CODE_EXTENSIONS,
					self::IMAGE_EXTENSIONS,
					self::DOCUMENT_EXTENSIONS
				),
				'max_file_size' => self::MAX_FILE_SIZE,

				'integrity_check'     => true,
				'vulnerability_check' => true,
				'estimated_time'      => '5-15 minutes',
			],
		];

		return $configs[ $type ] ?? $configs[ self::STANDARD ];
	}

	/**
	 * Get all available scan types with metadata for the UI.
	 *
	 * @return array<string, array<string, mixed>>
	 */
	public static function get_available_types(): array {
		return [
			self::STANDARD => [
				'name'        => 'Standard Scan',
				'description' => 'Integrity check and targeted malware scan on anomalous files',
				'recommended' => true,
				'time'        => '1-3 min',
			],
			self::DEEP => [
				'name'        => 'Deep Scan',
				'description' => 'Full scan including images; bypasses hash cache for fresh cloud verdicts',
				'recommended' => false,
				'time'        => '5-15 min',
			],
		];
	}

	/**
	 * Whether a file extension belongs to the image/document group that requires
	 * a local binary content check before cloud escalation in deep scan.
	 *
	 * @param string $extension Lowercase file extension (no leading dot).
	 * @return bool
	 */
	public static function is_binary_check_extension( string $extension ): bool {
		return in_array( $extension, self::IMAGE_EXTENSIONS, true )
			|| in_array( $extension, self::DOCUMENT_EXTENSIONS, true );
	}
}
