<?php

namespace EasyCriticalCSS;

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

/**
 * This file is for compatibility purposes and will not use the easy_cc prefix.
 * phpcs:disable WordPress.NamingConventions.PrefixAllGlobals
 */

class Compatibility_Cache {
	public static function init() {
		add_action( 'easy_cc_all_expired', [ __CLASS__, 'clear_cache_all' ] );
		add_action( 'easy_cc_single_expired', [ __CLASS__, 'clear_cache_single' ] );
		add_action( 'easy_cc_single_generated', [ __CLASS__, 'clear_cache_single' ] );
	}

	private static function call_function_if_exists( $function_name, ...$args ) {
		if ( function_exists( $function_name ) ) {
			call_user_func_array( $function_name, $args );
		}
	}

	private static function call_if_callable( $callback, ...$args ) {
		if ( is_callable( $callback ) ) {
			call_user_func_array( $callback, $args );
		}
	}

	private static function do_action_if( $tag, ...$args ) {
		if ( has_action( $tag ) ) {
			array_unshift( $args, $tag );
			call_user_func_array( 'do_action', $args );
		}
	}

	// Shoutout to Autoptimize for figuring most of this out!
	public static function clear_cache_all() {
		// WP Rocket.
		self::call_function_if_exists( 'rocket_clean_domain' );

		// WP Super Cache.
		if ( function_exists( 'wp_cache_clear_cache' ) ) {
			if ( is_multisite() ) {
				$blog_id = get_current_blog_id();
				wp_cache_clear_cache( $blog_id );
			} else {
				wp_cache_clear_cache();
			}
		}

		// Cachify.
		self::do_action_if( 'cachify_flush_cache' );

		// W3 Total Cache.
		self::call_function_if_exists( 'w3tc_pgcache_flush' );

		// WP Fast Cache.
		self::call_function_if_exists( 'wp_fast_cache_bulk_delete_all' );

		// Rapid Cache.
		self::call_function_if_exists( 'rapidcache_clear_cache' );

		// Swift Performance Cache.
		self::call_if_callable( [ 'Swift_Performance_Cache', 'clear_all_cache' ] );

		// WP Fastest Cache.
		if ( class_exists( 'WpFastestCache' ) ) {
			$wpfc = new \WpFastestCache();
			if ( method_exists( $wpfc, 'deleteCache' ) ) {
				$wpfc->deleteCache();
			}
		}

		// Quick Cache.
		self::call_if_callable( [ 'c_ws_plugin__qcache_purging_routines', 'purge_cache_dir' ] );

		// Zencache.
		self::call_if_callable( [ 'WebSharks\\ZenCache\\ApiBase', 'clear' ] );

		// Comet Cache.
		self::call_if_callable( [ 'WebSharks\\CometCache\\Pro\\Classes\\ApiBase', 'clear' ] );

		// WP Engine.
		if ( class_exists( 'WpeCommon' ) ) {
			// WPEngine cache purge/flush methods to call by default
			$wpe_methods = [
				'purge_varnish_cache',
			];

			// More agressive clear/flush/purge behind a filter
			if ( apply_filters( 'autoptimize_flush_wpengine_aggressive', false ) ) {
				$wpe_methods = array_merge( $wpe_methods, [ 'purge_memcached', 'clear_maxcdn_cache' ] );
			}

			// Filtering the entire list of WpeCommon methods to be called (for advanced usage + easier testing)
			$wpe_methods = apply_filters( 'autoptimize_flush_wpengine_methods', $wpe_methods );

			foreach ( $wpe_methods as $wpe_method ) {
				if ( method_exists( 'WpeCommon', $wpe_method ) ) {
					\WpeCommon::$wpe_method();
				}
			}
		}

		// Siteground.
		self::call_function_if_exists( 'sg_cachepress_purge_cache' );

		// Kinsta.
		if ( array_key_exists( 'KINSTA_CACHE_ZONE', $_SERVER ) ) {
			$_kinsta_clear_cache_url = 'https://localhost/kinsta-clear-cache-all'; // phpcs:ignore PluginCheck.CodeAnalysis.Localhost.Found -- This localhost is code specific for Kinsta
			$_kinsta_response        = wp_remote_get(
				$_kinsta_clear_cache_url,
				[
					'sslverify' => false,
					'timeout'   => 5,
				]
			);
		}

		// Raidboxes.
		if ( class_exists( 'RaidboxesNginxCacheFunctions' ) ) {
			$rb_cache_helper = new \RaidboxesNginxCacheFunctions();
			if ( method_exists( $rb_cache_helper, 'purge_cache' ) ) {
				$rb_cache_helper->purge_cache();
			}
		}

		// Nginx Helper.
		self::do_action_if( 'rt_nginx_helper_purge_all' );

		// Nginx Cache.
		if ( class_exists( 'NginxCache' ) ) {
			$nginx_cache = new \NginxCache();
			if ( method_exists( $nginx_cache, 'purge_zone_once' ) ) {
				$nginx_cache->purge_zone_once();
			}
		}

		// LiteSpeed Cache.
		self::do_action_if( 'litespeed_purge_all' );

		// Cloudflare (if API details exist).
		Compatibility_Cloudflare::clear_cloudflare_cache();
	}

	public static function clear_cache_by_id( $post_id ) {
		// WP Rocket.
		self::call_function_if_exists( 'rocket_clean_post', $post_id );

		// WP Super Cache.
		self::call_function_if_exists( 'wpsc_delete_post_cache', $post_id );

		// Cachify.
		self::call_if_callable( [ 'Cachify', 'remove_page_cache_by_post_id' ], $post_id );

		// W3 Total Cache.
		self::call_function_if_exists( 'w3tc_flush_post', $post_id );

		// Rapid Cache.
		self::call_function_if_exists( 'rapidcache_clear_post_cache', $post_id );

		// Swift Performance Cache.
		if ( class_exists( 'Swift_Performance_Cache' ) ) {
			\Swift_Performance_Cache::clear_all_cache();
		}

		// WP Fastest Cache.
		if ( class_exists( 'WpFastestCache' ) ) {
			$wpfc = new \WpFastestCache();
			$wpfc->singleDeleteCache( false, $post_id );
		}

		// Zencache.
		self::call_if_callable( [ 'WebSharks\\ZenCache\\ApiBase', 'clearPost' ], $post_id );

		// Comet Cache.
		self::call_if_callable( [ 'WebSharks\\CometCache\\Pro\\Classes\\ApiBase', 'clearPost' ], $post_id );

		// LiteSpeed Cache.
		self::do_action_if( 'litespeed_purge_post', $post_id );
	}

	public static function clear_cache_by_url( $url ) {
		// WP Rocket.
		self::call_function_if_exists( 'rocket_clean_files', $url );

		// WP Super Cache.
		self::call_function_if_exists( 'wpsc_delete_url_cache', $url );

		// Cachify.
		self::call_if_callable( [ 'Cachify', 'remove_page_cache_by_url' ], $url );

		// W3 Total Cache.
		self::call_function_if_exists( 'w3tc_flush_url', $url );

		// Rapid Cache.
		self::call_function_if_exists( 'rapidcache_clear_url_cache', $url );

		// Zencache.
		self::call_if_callable( [ 'WebSharks\\ZenCache\\ApiBase', 'clearUrl' ], $url );

		// Comet Cache.
		self::call_if_callable( [ 'WebSharks\\CometCache\\Pro\\Classes\\ApiBase', 'clearUrl' ], $url );

		// LiteSpeed Cache.
		self::do_action_if( 'litespeed_purge_url', $url );
	}

	public static function clear_cache_by_url_only( $url ) {
		// WP Fast Cache.
		if ( function_exists( 'wp_fast_cache_build_url_from_file' ) && function_exists( 'wp_fast_cache_delete_cached_url' ) ) {
			$built_url = wp_fast_cache_build_url_from_file( $url );
			wp_fast_cache_delete_cached_url( $built_url );
		}

		// Kinsta.
		if ( array_key_exists( 'KINSTA_CACHE_ZONE', $_SERVER ) ) {
			$relative_path           = str_replace( home_url(), '', $url );
			$_kinsta_clear_cache_url = home_url( '/kinsta-clear-cache' . untrailingslashit( $relative_path ) );
			$_kinsta_response        = wp_remote_get(
				$_kinsta_clear_cache_url,
				[
					'sslverify' => false,
					'timeout'   => 5,
				]
			);
		}

		// Nginx Helper.
		$nginx_purger = null;
		if ( class_exists( 'PhpRedis_Purger' ) ) {
			$nginx_purger = new \PhpRedis_Purger();
		} elseif ( class_exists( 'FastCGI_Purger' ) ) {
			$nginx_purger = new \FastCGI_Purger();
		} elseif ( class_exists( 'Redis_Purger' ) ) {
			$nginx_purger = new \Redis_Purger();
		}
		if ( $nginx_purger !== null && method_exists( $nginx_purger, 'purge_url' ) ) {
			$nginx_purger->purge_url( $url );
		}

		// Cloudflare (if API details exist).
		Compatibility_Cloudflare::clear_cloudflare_cache( $url );
	}

	public static function clear_cache_single( $identifier ) {
		// Caching plugins already clear their own cache on post_update
		if ( doing_action( 'post_updated' ) ) {
			return;
		}

		// Get URL and post IDs from identifier if possible.
		$post_id = Helpers::get_post_id_from_identifier( $identifier );
		$url     = Helpers::get_url_from_identifier( $identifier );

		// Clear cache by post_id if exists.
		if ( ! empty( $post_id ) ) {
			self::clear_cache_by_id( $post_id );
		}

		// Clear cache by url if exists.
		if ( ! empty( $url ) ) {
			self::clear_cache_by_url_only( $url );

			// Prevent duplicate cache clears by only running these if post_id doesn't exist.
			if ( empty( $post_id ) ) {
				self::clear_cache_by_url( $url );
			}
		}
	}
}
