<?php
/**
 * Helpers for the JSON Schema subset used by module settings.
 *
 * @package MenuVerse
 */

namespace WPXero\MenuVerse\Settings;

defined( 'ABSPATH' ) || exit;

/**
 * Derives defaults and REST argument definitions from a settings schema.
 */
final class Schema {

	/**
	 * Builds the default value tree for a schema.
	 *
	 * @param array $schema Schema definition.
	 * @return mixed
	 */
	public static function defaults( array $schema ) {
		$type = isset( $schema['type'] ) ? $schema['type'] : 'string';

		if ( 'object' === $type ) {
			$defaults = array();

			if ( ! empty( $schema['properties'] ) && is_array( $schema['properties'] ) ) {
				foreach ( $schema['properties'] as $key => $property ) {
					$defaults[ $key ] = self::defaults( (array) $property );
				}
			}

			return $defaults;
		}

		if ( array_key_exists( 'default', $schema ) ) {
			return $schema['default'];
		}

		switch ( $type ) {
			case 'array':
				return array();
			case 'boolean':
				return false;
			case 'integer':
			case 'number':
				return 0;
			default:
				return '';
		}
	}

	/**
	 * Builds REST argument definitions from the top level of an object schema.
	 *
	 * Nested rules are enforced by the validator; this only gives WordPress
	 * enough information to reject obviously malformed requests early.
	 *
	 * @param array $schema Object schema definition.
	 * @return array
	 */
	public static function to_rest_args( array $schema ) {
		$args = array();

		if ( empty( $schema['properties'] ) || ! is_array( $schema['properties'] ) ) {
			return $args;
		}

		foreach ( $schema['properties'] as $key => $property ) {
			$property = (array) $property;
			$arg      = array(
				'required' => false,
				'type'     => isset( $property['type'] ) ? $property['type'] : 'string',
			);

			foreach ( array( 'enum', 'minimum', 'maximum', 'minLength', 'maxLength', 'pattern', 'default' ) as $keyword ) {
				if ( isset( $property[ $keyword ] ) ) {
					$arg[ $keyword ] = $property[ $keyword ];
				}
			}

			$args[ $key ] = $arg;
		}

		return $args;
	}

	/**
	 * Strips UI hints so the schema can be validated as plain JSON Schema.
	 *
	 * @param array $schema Schema definition.
	 * @return array
	 */
	public static function strip_ui( array $schema ) {
		unset( $schema['ui'] );

		if ( ! empty( $schema['properties'] ) && is_array( $schema['properties'] ) ) {
			foreach ( $schema['properties'] as $key => $property ) {
				$schema['properties'][ $key ] = self::strip_ui( (array) $property );
			}
		}

		if ( ! empty( $schema['items'] ) && is_array( $schema['items'] ) ) {
			$schema['items'] = self::strip_ui( $schema['items'] );
		}

		return $schema;
	}
}
