<?php
/**
 * Recurrence safety validation.
 *
 * @package ScheduledChanges
 */

namespace ScheduledChanges\Scheduler;

use ScheduledChanges\Domain\Operation\OperationGraph;
use ScheduledChanges\Domain\Operation\OperationType;
use ScheduledChanges\Validation\ValidationIssue;
use ScheduledChanges\Validation\ValidationLevel;
use ScheduledChanges\Validation\ValidationReport;

/**
 * Blocks recurrence for creation, additive, destructive, and external effects.
 */
final class RecurrenceSafetyValidator {
	public function validate( OperationGraph $graph ): ValidationReport {
		$issues = array();
		$unsafe = array(
			OperationType::ADD_LIST_ITEM,
			OperationType::REMOVE_LIST_ITEM,
			OperationType::ADD_TAXONOMY_TERM,
			OperationType::REMOVE_TAXONOMY_TERM,
			OperationType::CREATE_TAXONOMY_TERM,
		);

		foreach ( $graph->operations() as $operation ) {
			if ( ! in_array( $operation->type(), $unsafe, true ) ) {
				continue;
			}

			$issues[] = new ValidationIssue(
				'recurrence.operation_unsafe',
				'Operation is not safe for recurrence without an occurrence ledger or explicit reuse behavior.',
				ValidationLevel::BLOCKING_ERROR,
				'operations.' . $operation->uuid()->value(),
				array( 'operation_type' => $operation->type() )
			);
		}

		return new ValidationReport( $issues );
	}

	public function validateRule( string $rule ): ValidationReport {
		try {
			RecurrenceRule::parse( $rule );

			return ValidationReport::valid();
		} catch ( \InvalidArgumentException $exception ) {
			return new ValidationReport(
				array(
					new ValidationIssue(
						'recurrence.rule_invalid',
						$exception->getMessage(),
						ValidationLevel::BLOCKING_ERROR,
						'launch.recurrence_rule'
					),
				)
			);
		}
	}
}
