<?php
/**
 * Immutable filesystem inspection scope.
 *
 * @package LocalGuardScanner
 */

namespace LocalGuardScanner\Domain\Scan;

/**
 * Normalizes and applies the directory exclusions captured for one scan.
 */
final class InspectionScope {
	/** @var string[] */
	private $exclusions;

	/**
	 * @param mixed[] $exclusions Relative directory prefixes.
	 */
	public function __construct( array $exclusions = array() ) {
		$normalized = array();
		foreach ( $exclusions as $prefix ) {
			if ( ! is_string( $prefix ) ) {
				continue;
			}
			$prefix = trim( trim( str_replace( '\\', '/', $prefix ) ), '/' );
			if ( '' === $prefix || false !== strpos( $prefix, '..' ) || false !== strpos( $prefix, '://' ) ) {
				continue;
			}
			$normalized[ $prefix ] = $prefix;
		}
		$this->exclusions = array_values( $normalized );
	}

	/** @return string[] */
	public function exclusions() {
		return $this->exclusions;
	}

	/**
	 * @param string $locator Relative file or directory locator.
	 * @return bool
	 */
	public function excludes( $locator ) {
		$locator = trim( str_replace( '\\', '/', (string) $locator ), '/' );
		foreach ( $this->exclusions as $prefix ) {
			if ( $locator === $prefix || 0 === strpos( $locator . '/', $prefix . '/' ) ) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @param array<string,string> $manifest Expected file hashes keyed by locator.
	 * @return array<string,string>
	 */
	public function filter_manifest( array $manifest ) {
		foreach ( array_keys( $manifest ) as $locator ) {
			if ( $this->excludes( $locator ) ) {
				unset( $manifest[ $locator ] );
			}
		}
		return $manifest;
	}
}
