<?php
/**
 * Validates URL-shaped Schema.org values.
 *
 * @package SEOvaultSEO\Schema\Validation\Rules\Core
 */

namespace SEOvaultSEO\Schema\Validation\Rules\Core;

use SEOvaultSEO\Schema\Validation\RuleInterface;
use SEOvaultSEO\Schema\Validation\Severity;
use SEOvaultSEO\Schema\Validation\ValidationContext;
use SEOvaultSEO\Schema\Validation\ValidationIssue;
use SEOvaultSEO\Schema\Validation\ValueInspector;

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

/**
 * Reports malformed HTTP(S) URLs without dereferencing any URL.
 */
class UrlValueRule implements RuleInterface {

	/**
	 * Get the stable rule code.
	 *
	 * @return string
	 */
	public function get_code() {
		return 'schema.value.invalid_url';
	}

	/**
	 * URL checks apply to every graph.
	 *
	 * @param ValidationContext $context Validation context.
	 * @return bool
	 */
	public function supports( ValidationContext $context ) {
		return true;
	}

	/**
	 * Validate URL-shaped string values.
	 *
	 * @param ValidationContext $context Validation context.
	 * @return ValidationIssue[]
	 */
	public function evaluate( ValidationContext $context ) {
		$issues = array();
		foreach ( $context->get_entities() as $entity ) {
			if ( empty( $entity['is_top_level'] ) ) {
				continue;
			}

			ValueInspector::walk(
				$entity['data'] ?? array(),
				$entity['path'] ?? '',
				function ( $property, $value, $path ) use ( &$issues, $entity, $context ) {
					if ( ! ValueInspector::is_url_property( $property ) || ! is_string( $value ) || ValueInspector::is_empty( $value ) || ValueInspector::is_valid_url( $value, $property ) ) {
						return;
					}

					$issues[] = new ValidationIssue(
						array(
							'code'        => 'schema.value.invalid_url',
							'severity'    => Severity::WARNING,
							'category'    => 'core',
							'entity_type' => implode( ', ', $entity['types'] ?? array() ),
							'entity_id'   => $entity['id'] ?? '',
							'path'        => $path,
							'source'      => $context->get_source(),
							'title_key'   => 'schema.value_invalid_url.title',
							'message_key' => 'schema.value_invalid_url.message',
						)
					);
				}
			);
		}

		return $issues;
	}
}
