<?php

/**
 * Registry of static safety rules for built artifacts.
 *
 * @package LolaCore\Builder\Safety
 * @license GPL-2.0-or-later
 */

declare(strict_types=1);

namespace LolaCore\Builder\Safety;

use LolaCore\Builder\Safety\Rules\DirectFileAccessRule;
use LolaCore\Builder\Safety\Rules\EarlyWooCommerceExitRule;
use LolaCore\Builder\Safety\Rules\ForbiddenFunctionsRule;
use LolaCore\Builder\Safety\Rules\StrippedVendorNamespaceRule;
use LolaCore\Builder\Safety\Rules\UnknownParentClassAtFileScopeRule;

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

/**
 * Provides the default Capa A rule set and allows extensions via filter.
 *
 * The filter hook is supplied by the consumer so each artifact kind keeps its
 * own extension point (the Plugin Builder passes lolacore_pb_safety_rules).
 */
class SafetyRuleRegistry {

	/** @var array<int, SafetyRuleInterface>|null */
	private ?array $rules = null;

	public function __construct( private string $filterHook = '' ) {
	}

	/**
	 * @return array<int, SafetyRuleInterface>
	 */
	public function getRules(): array {
		if ($this->rules !== null) {
			return $this->rules;
		}

		$defaultRules = array(
			new StrippedVendorNamespaceRule(),
			new UnknownParentClassAtFileScopeRule(),
			new EarlyWooCommerceExitRule(),
			new DirectFileAccessRule(),
			new ForbiddenFunctionsRule(),
		);

		$filtered = $defaultRules;
		if ($this->filterHook !== '') {
			/**
			 * Filters the static safety rules executed before runtime validation and LLM review.
			 *
			 * @param array<int, SafetyRuleInterface> $defaultRules Default Capa A rules.
			 */
			// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound -- Filter hook is constructor-injected and always lolacore-prefixed by callers.
			$filtered = apply_filters($this->filterHook, $defaultRules);
		}

		$this->rules = array_values(
			array_filter(
				$filtered,
				static fn( $rule ): bool => $rule instanceof SafetyRuleInterface
			)
		);

		return $this->rules;
	}
}
