<?php
/**
 * Preload
 * @author Alexander Kovalev <alex.kovalevv@gmail.com>
 * @copyright (c) 09.03.2021, CreativeMotion
 * @version 1.0
 */

class WCL_Preload {

	/**
	 * Clearfy CDN instance.
	 *
	 * @since 1.2.1
	 *
	 * @var WCL_CDN
	 */
	private $cdn;

	/**
	 * Font formats allowed to be preloaded.
	 *
	 * @since 1.2.1
	 * @see $this->sanitize_font()
	 *
	 * @var string|bool
	 */
	private $font_formats = [
		'otf',
		'ttf',
		'svg',
		'woff',
		'woff2',
	];

	public function __construct()
	{
		require_once 'class-cdn.php';
		$this->cdn = new WCL_CDN();

		add_action("wp_head", [$this, "preload_fonts"], 0);
		add_filter('wp_resource_hints', [$this, 'dns_prefetch'], 10, 2);
	}

	/**
	 * Adds domain names to the list of DNS Prefetch printed by wp_resource_hints
	 *
	 * @param Array $hints URLs to print for resource hints.
	 * @param String $relation_type The relation type the URL are printed for.
	 * @return Array URLs to print
	 *
	 * @since 1.2.1
	 */
	function dns_prefetch($hints, $relation_type)
	{
		$domains = WCL_Plugin::app()->getPopulateOption('urls_prefetch');

		if( !empty($domains) ) {
			$domains = preg_split('/\r\n|\n|\r/', $domains);
		} else {
			$domains = [];
		}

		/**
		 * Filters the list of fonts to preload
		 *
		 * @param array $fonts Array of fonts paths.
		 * @since 1.2.1
		 *
		 */
		$domains = (array)apply_filters('wclearfy/performance/preload/prefetch_domains', $domains);
		$domains = array_map([$this, 'sanitize_prefetch_url'], $domains);
		$domains = array_filter(array_unique($domains));

		if( (bool)$domains ) {
			foreach($domains as $domain) {
				if( 'dns-prefetch' === $relation_type ) {
					$hints[] = $domain;
				}
			}
		}

		return $hints;
	}

	/**
	 * Add the required <link/> tags used to preload fonts.
	 *
	 * @since 1.2.1
	 */
	public function preload_fonts()
	{
		$fonts = WCL_Plugin::app()->getPopulateOption('preload_fonts');

		if( !empty($fonts) ) {
			$fonts = preg_split('/\r\n|\n|\r/', $fonts);
		} else {
			$fonts = [];
		}

		/**
		 * Filters the list of fonts to preload
		 *
		 * @param array $fonts Array of fonts paths.
		 * @since 1.2.1
		 *
		 */
		$fonts = (array)apply_filters('wclearfy/performance/preload/fonts', $fonts);
		$fonts = array_map([$this, 'sanitize_font'], $fonts);
		$fonts = array_filter($fonts);

		if( empty($fonts) ) {
			return;
		}

		$base_url = wp_parse_url(home_url());
		$base_url = "{$base_url['scheme']}://{$base_url['host']}";

		foreach(array_unique($fonts) as $font) {
			printf("\n<link rel=\"preload\" as=\"font\" href=\"%s\" crossorigin>", esc_url($this->cdn->rewrite_url($base_url . $font)));
		}
	}

	/**
	 * Sanitize a font file path.
	 *
	 * @param string $file Filepath to sanitize.
	 * @return string|bool  Sanitized filepath. False if not a font file.
	 * @since 1.2.1
	 *
	 */
	private function sanitize_font($file)
	{
		if( !is_string($file) ) {
			return false;
		}

		$file = trim($file);

		if( empty($file) ) {
			return false;
		}

		$ext = strtolower(pathinfo(wp_parse_url($file, PHP_URL_PATH), PATHINFO_EXTENSION));

		if( !in_array($ext, $this->font_formats, true) ) {
			return false;
		}

		return $file;
	}

	/**
	 * Sanitize a font file path.
	 *
	 * @param string $file Filepath to sanitize.
	 * @return string|bool  Sanitized filepath. False if not a font file.
	 * @since 1.2.1
	 *
	 */
	private function sanitize_prefetch_url($url)
	{
		if( !is_string($url) ) {
			return false;
		}

		$url = trim($url);

		if( empty($url) ) {
			return false;
		}

		$url = str_replace(['http://', 'https://'], '//', $url);

		return $url;
	}
}