<?php
namespace Kanews\Util;

class Speed {

  private static $instance;

  public static function getInstance() {
    if ( null === static::$instance ) {
      static::$instance = new static();
    }
    return static::$instance;
  }

	function __construct() {
		if( ! kanews_get_option('kanews-speed') )
		return;
	
		add_action( 'wp_resource_hints',             array( $this, 'resource_hints' ), 10, 2 );
		add_action( 'wp_head',             			 array( $this, 'preload_resources' ), 1 );
		add_filter( 'script_loader_tag',             array( $this, 'add_defer_attribute' ), 10, 2 );
		
		add_filter( 'xmlrpc_enabled',                '__return_false', 5 );
		
		if ( kanews_get_option( 'kanews-speed-remove-rsd', true ) ) {
			remove_action( 'wp_head',                    'rsd_link' );
		}

		remove_action( 'wp_head',                    'wlwmanifest_link' );
		
		remove_filter( 'the_title',                  'capital_P_dangit', 11 );
		remove_filter( 'the_content',                'capital_P_dangit', 11 );
		remove_filter( 'comment_text',               'capital_P_dangit', 31 );
		remove_filter( 'wp_title',              		 'capital_P_dangit', 31 );
		
		add_filter( 'wpcf7_load_js',                 '__return_false' );
		add_filter( 'wpcf7_load_css',                '__return_false' );
		
		add_filter( 'script_loader_src',  			 array( $this, 'remove_query_strings' ), 15, 2 );
		add_filter( 'style_loader_src',   			 array( $this, 'remove_query_strings' ), 15, 2 );

		if ( kanews_get_option( 'kanews-speed-remove-emoji', true ) ) {
			$this->disable_emojis();
		}

		if ( kanews_get_option( 'kanews-speed-remove-oembed', true ) ) {
			$this->disable_oembed();
		}

		if ( kanews_get_option( 'kanews-speed-remove-wp-version', true ) ) {
			$this->remove_wp_version_meta();
		}

		if ( kanews_get_option( 'kanews-speed-remove-global-styles', true ) ) {
			$this->remove_global_styles();
		}

		if ( kanews_get_option( 'kanews-speed-remove-rest-api', false ) ) {
			$this->disable_rest_api();
		}

		if ( kanews_get_option( 'kanews-speed-remove-block-styles', true ) ) {
			add_action( 'wp_enqueue_scripts', array( $this, 'remove_block_library_styles' ), 100 );
			add_action( 'enqueue_block_editor_assets', array( $this, 'remove_block_editor_assets' ), 100 );
		}

		if ( kanews_get_option( 'kanews-speed-remove-classic-theme-styles', true ) ) {
			$this->remove_classic_theme_styles();
		}
		
	}


	// Resource
	function resource_hints( $hints, $relation_type ) {

		if ( 'dns-prefetch' === $relation_type && kanews_get_option('kanews-dns-prefetch', true) ) {
			$hints[] = '//s.gravatar.com';
			$hints[] = '//fonts.googleapis.com';
			$hints[] = '//fonts.gstatic.com';
			$hints[] = '//cdnjs.cloudflare.com';
			$hints[] = '//www.google-analytics.com';
		}

		return $hints;
	
	}
	
	// Preload
	function preload_resources(){

		if(!kanews_get_option('kanews-preload', true))
		return false;
		
		// Styles
		if( wp_style_is( 'kanews-theme' ) ) 
		echo "<link rel='preload' as='style' href='".get_template_directory_uri()."/assets/css/theme.min.css' />\n";

		// Styles
		if( wp_style_is( 'kanews-theme-single' ) && is_singular() ) 
		echo "<link rel='preload' as='style' href='".get_template_directory_uri()."/assets/css/theme-single.min.css' />\n";

		// Fonts
		echo "<link rel='preload' as='font' href='".get_template_directory_uri()."/assets/fonts/icomoon.woff' type='font/woff' crossorigin='anonymous' />\n";

	}

	function remove_query_strings($src, $handle) {
		if($handle != 'child-style'){
			$src = remove_query_arg('ver', $src);
		}
		return $src;
	}
	
	// Add Defer
	function add_defer_attribute( $tag, $handle ) {

		if(!kanews_get_option('kanews-js-defer', true))
		return $tag;

		if ( ( strpos( $handle, 'kanews-') !== false || strpos( $handle, 'comment-reply') !== false ) && ! is_admin() ) {
			return str_replace( ' src', ' defer="defer" src', $tag );
		}

		return $tag;
	}

	private function disable_emojis() {
		remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
		remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
		remove_action( 'wp_print_styles', 'print_emoji_styles' );
		remove_action( 'admin_print_styles', 'print_emoji_styles' );
		remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
		remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
		remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
		remove_filter( 'the_excerpt', 'convert_smilies' );
		remove_filter( 'the_post_thumbnail_caption', 'convert_smilies' );
		remove_filter( 'the_content', 'convert_smilies', 20 );
		remove_filter( 'comment_text', 'convert_smilies', 20 );
		remove_filter( 'widget_text_content', 'convert_smilies', 20 );
		add_filter( 'tiny_mce_plugins', array( $this, 'disable_emojis_tinymce' ) );
		add_filter( 'emoji_svg_url', '__return_false' );
	}

	public function disable_emojis_tinymce( $plugins ) {
		if ( is_array( $plugins ) ) {
			return array_diff( $plugins, array( 'wpemoji' ) );
		}

		return array();
	}

	private function disable_oembed() {
		remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );
		remove_action( 'wp_head', 'wp_oembed_add_host_js' );
		remove_action( 'rest_api_init', 'wp_oembed_register_route' );
		remove_filter( 'oembed_dataparse', 'wp_filter_oembed_result', 10 );

		add_filter( 'embed_oembed_discover', '__return_false' );
		add_filter( 'pre_oembed_result', '__return_false' );
		add_filter( 'rewrite_rules_array', array( $this, 'disable_embeds_rewrites' ) );
		add_filter( 'request', array( $this, 'disable_embeds_parse_query' ) );
		add_filter( 'tiny_mce_plugins', array( $this, 'disable_embeds_tiny_mce_plugin' ) );
	}

	public function disable_embeds_rewrites( $rules ) {
		foreach ( $rules as $rule => $rewrite ) {
			if ( false !== strpos( $rewrite, 'embed=true' ) ) {
				unset( $rules[ $rule ] );
			}
		}

		return $rules;
	}

	public function disable_embeds_parse_query( $query_vars ) {
		if ( isset( $query_vars['embed'] ) ) {
			unset( $query_vars['embed'] );
		}

		return $query_vars;
	}

	public function disable_embeds_tiny_mce_plugin( $plugins ) {
		if ( is_array( $plugins ) ) {
			return array_diff( $plugins, array( 'wpembed' ) );
		}

		return array();
	}

	private function remove_wp_version_meta() {
		remove_action( 'wp_head', 'wp_generator' );
		add_filter( 'the_generator', '__return_empty_string' );
	}

	private function remove_global_styles() {
		if ( function_exists( 'wp_enqueue_global_styles' ) ) {
			remove_action( 'wp_enqueue_scripts', 'wp_enqueue_global_styles' );
		}

		if ( function_exists( 'wp_global_styles_render_svg_filters' ) ) {
			remove_action( 'wp_body_open', 'wp_global_styles_render_svg_filters' );
		}

		remove_action( 'wp_enqueue_scripts', 'wp_enqueue_global_styles', 1 );
		remove_action( 'wp_print_styles', 'wp_print_global_styles', 1 );
		add_action( 'wp_enqueue_scripts', array( $this, 'dequeue_global_styles' ), 100 );
	}
	public function dequeue_global_styles() {
		wp_dequeue_style( 'global-styles' );
	}


	private function disable_rest_api() {
		add_filter( 'rest_enabled', '__return_false' );
		add_filter( 'rest_jsonp_enabled', '__return_false' );

		remove_action( 'wp_head', 'rest_output_link_wp_head' );
		remove_action( 'template_redirect', 'rest_output_link_header', 11, 0 );
		remove_action( 'xmlrpc_rsd_apis', 'rest_output_rsd' );

		add_filter( 'rest_authentication_errors', array( $this, 'disable_rest_api_access' ), 99 );
	}

	public function disable_rest_api_access( $result ) {
		if ( empty( $result ) || ! is_wp_error( $result ) ) {
			return new \WP_Error(
				'rest_disabled',
				__( 'REST API disabled.', 'kanews' ),
				array( 'status' => 403 )
			);
		}

		return $result;
	}

	public function remove_block_library_styles() {
		wp_dequeue_style( 'wp-block-library' );
		wp_dequeue_style( 'wp-block-library-theme' );
		wp_dequeue_style( 'wc-block-style' );
	}

	public function remove_block_editor_assets() {
		wp_dequeue_style( 'wp-block-library' );
		wp_dequeue_style( 'wp-block-library-theme' );
		wp_dequeue_style( 'wc-block-style' );
	}

	private function remove_classic_theme_styles() {
		if ( function_exists( 'wp_enqueue_classic_theme_styles' ) ) {
			remove_action( 'wp_enqueue_scripts', 'wp_enqueue_classic_theme_styles' );
		}

		add_action( 'wp_enqueue_scripts', array( $this, 'dequeue_classic_theme_styles' ), 100 );
	}

	public function dequeue_classic_theme_styles() {
		wp_dequeue_style( 'classic-theme-styles' );
	}

}
