<?php

declare(strict_types=1);

namespace SecurWP\Modules\Scanner\Service;

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

/**
 * MalwareFindingFormatter
 *
 * Normalizes user-facing malware threat labels and summary copy so hash-only
 * detections and deep-scan detections produce the same finding contract.
 */
class MalwareFindingFormatter {

	/**
	 * Preferred order for threat fields emitted by Intel Engine.
	 *
	 * @var array<int,string>
	 */
	private const THREAT_FIELDS = [
		'threat_type',
		'threat_name',
		'malware_family',
		'signature_name',
		'rule_name',
		'classification',
	];

	/**
	 * Normalize a malware payload to a stable display threat label.
	 *
	 * @param array $payload
	 * @return string
	 */
	public static function resolveThreatLabel( array $payload ): string {
		foreach ( self::THREAT_FIELDS as $field ) {
			$value = trim( (string) ( $payload[ $field ] ?? '' ) );
			if ( $value !== '' ) {
				return self::formatThreatLabel( $value );
			}
		}

		return 'Known Malware';
	}

	/**
	 * Build the canonical end-user summary for malware findings.
	 *
	 * The copy is intentionally detection-path-neutral so the UI remains
	 * consistent whether the file was identified by deep scan or by a known
	 * malicious hash verdict.
	 *
	 * @param array  $payload
	 * @param string $file_path
	 * @return string
	 */
	public static function buildDescription( array $payload, string $file_path = '' ): string {
		$threat_label = self::resolveThreatLabel( $payload );
		$threat_key   = self::normalizeThreatKey( $threat_label );
		$parts        = [ self::buildThreatSummary( $threat_key, $threat_label ) ];

		$location_context = self::buildLocationContext( $file_path );
		if ( $location_context !== '' ) {
			$parts[] = $location_context;
		}

		$parts[] = 'Remove the file immediately or restore a verified clean copy, then review adjacent files, recent administrative activity, and deployment history for related compromise.';

		return implode( ' ', $parts );
	}

	/**
	 * Convert raw threat labels into consistent UI display text.
	 *
	 * @param string $value
	 * @return string
	 */
	public static function formatThreatLabel( string $value ): string {
		$value = trim( $value );
		if ( $value === '' ) {
			return 'Known Malware';
		}

		if ( strpos( $value, ':' ) !== false ) {
			$parts = explode( ':', $value, 2 );
			$value = trim( (string) ( $parts[0] ?? $value ) );
		}

		if ( strpos( $value, '/' ) !== false ) {
			$parts = explode( '/', $value, 2 );
			$value = trim( (string) ( $parts[0] ?? $value ) );
		}

		$value = preg_replace( '/\.\d+$/', '', $value ) ?: $value;

		$normalized = self::normalizeThreatKey( $value );

		$map = [
			'seospam'        => 'SEO Spam',
			'spam'           => 'Spam Injection',
			'ioc'            => 'Indicators of Compromise',
			'hacktool'       => 'Hacktool',
			'cryptominer'    => 'Cryptominer',
			'mailer'         => 'Spam Mailer',
			'uploader'       => 'Unauthorized Uploader',
			'suspiciouscode' => 'Suspicious Code',
		];

		if ( isset( $map[ $normalized ] ) ) {
			return $map[ $normalized ];
		}

		return $value;
	}

	/**
	 * @param string $value
	 * @return string
	 */
	private static function normalizeThreatKey( string $value ): string {
		$value = strtolower( trim( $value ) );
		if ( $value === '' ) {
			return 'knownmalware';
		}

		$collapsed = preg_replace( '/[^a-z0-9]+/', '', $value );
		return is_string( $collapsed ) && $collapsed !== '' ? $collapsed : 'knownmalware';
	}

	/**
	 * @param string $threat_key
	 * @param string $threat_label
	 * @return string
	 */
	private static function buildThreatSummary( string $threat_key, string $threat_label ): string {
		switch ( $threat_key ) {
			case 'backdoor':
				return 'This file matches a known backdoor malware pattern. Backdoors are used to regain unauthorized access, execute commands, and preserve attacker access after compromise.';

			case 'obfuscated':
				return 'This file matches a known obfuscated malware pattern. Obfuscation is commonly used to conceal malicious behavior, evade review, and reintroduce payloads after incomplete cleanup.';

			case 'phishing':
			case 'phishingattack':
				return 'This file matches a known phishing malware pattern. Phishing payloads are used to impersonate trusted brands, capture credentials, or redirect visitors to fraudulent pages.';

			case 'spam':
			case 'spaminjection':
			case 'seospam':
				return 'This file matches a known spam injection pattern. Spam malware is used to place unauthorized links, landing pages, or search-manipulation content on the site.';

			case 'cryptominer':
				return 'This file matches a known cryptomining pattern. Cryptomining malware abuses server or visitor resources and is often deployed alongside broader compromise activity.';

			case 'unauthorizeduploader':
			case 'uploader':
				return 'This file matches a known unauthorized uploader pattern. Upload shells are commonly used to place additional malware on the server after initial access is gained.';

			case 'spammailer':
			case 'mailer':
				return 'This file matches a known spam mailer pattern. Mailer malware is used to send unauthorized email, damage mail reputation, and support broader abuse from the server.';

			case 'hacktool':
				return 'This file matches a known offensive tool or post-compromise utility. These tools are commonly used to manage files, weaken defenses, or expand attacker control after intrusion.';

			case 'indicatorsofcompromise':
			case 'ioc':
				return 'This file matches a known post-compromise indicator pattern. Artifacts of this type are commonly associated with persistence, credential theft, exfiltration, or malicious automation.';

			case 'suspicious':
			case 'suspiciouscode':
				return 'This file matches a known suspicious malware pattern. The detected behavior is commonly associated with concealed execution paths, loaders, or malicious automation.';

			case 'trojan':
				return 'This file matches a known trojan malware pattern. Trojanized files are used to appear legitimate while performing unauthorized actions in the background.';

			default:
				return sprintf(
					'This file matches a known %s malware pattern. Files of this type are commonly used to execute unauthorized actions, redirect traffic, steal data, or maintain persistence after compromise.',
					strtolower( $threat_label )
				);
		}
	}

	/**
	 * @param string $file_path
	 * @return string
	 */
	private static function buildLocationContext( string $file_path ): string {
		$normalized = '/' . ltrim( strtolower( wp_normalize_path( $file_path ) ), '/' );

		if ( $normalized === '/wp-config.php' ) {
			return 'The finding affects the WordPress configuration layer, which should be handled with controlled manual remediation and source validation.';
		}

		if ( strpos( $normalized, '/wp-content/uploads/' ) === 0 ) {
			return 'Executable code in the uploads directory is rarely legitimate and should be treated as a likely compromise until proven otherwise.';
		}

		if ( strpos( $normalized, '/wp-content/plugins/' ) === 0 ) {
			return 'The file is located inside a plugin directory. Confirm whether it belongs to the vendor\'s verified release or an approved customization.';
		}

		if ( strpos( $normalized, '/wp-content/themes/' ) === 0 ) {
			return 'The file is located inside a theme directory. Confirm whether it belongs to the verified theme package or an approved customization.';
		}

		if ( strpos( $normalized, '/wp-admin/' ) === 0 || strpos( $normalized, '/wp-includes/' ) === 0 ) {
			return 'The file is located in a protected WordPress core directory, where unauthorized code can affect platform integrity and site-wide execution.';
		}

		if ( strpos( $normalized, '/wp-content/' ) === 0 ) {
			return 'The file is located within the WordPress content area. Review nearby files for unauthorized additions, replacements, or persistence mechanisms.';
		}

		return '';
	}
}
