<?php
/**
 * Stable finding fingerprint.
 *
 * @package LocalGuardScanner
 */

namespace LocalGuardScanner\Domain\Detection;

use RuntimeException;

/**
 * Generates a versioned SHA-256 identity from material evidence.
 */
final class FindingFingerprint {
	const VERSION = '1';

	/**
	 * @param Finding $finding Finding.
	 * @return string
	 */
	public function for_finding( Finding $finding ) {
		$detectors = array();
		foreach ( $finding->evidence() as $evidence ) {
			$detectors[] = $evidence->detector_id() . ':' . $evidence->message_key();
		}
		sort( $detectors, SORT_STRING );
		$payload = array(
			'v'        => self::VERSION,
			'type'     => $finding->object_type(),
			'locator'  => str_replace( '\\', '/', $finding->locator() ),
			'evidence' => $detectors,
		);
		$encoded = json_encode( $payload, JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE ); // phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode
		if ( false === $encoded ) {
			throw new RuntimeException( 'Finding identity could not be encoded safely.' );
		}
		return hash( 'sha256', $encoded );
	}
}
