<?php

namespace Sphere\Debloat\Admin;
use Sphere\Debloat\Plugin;

/**
 * Cache clear, stats and similar for admin area.
 * 
 * @author  asadkn
 * @since   1.0.0
 */
class Cache
{
	protected $deleting = false;

	public function init()
	{
		$this->register_clear_hooks();
	}

	/**
	 * Register hooks to clear cache.
	 *
	 * @return void
	 */
	public function register_clear_hooks()
	{
		/**
		 * Use this hook to clear caches externally.
		 */
		add_action('debloat/empty_caches', [$this, 'empty']);

		/**
		 * Other plugin hooks to empty cache on.
		 */ 
		$hooks = [
			// WP Rocket.
			'after_rocket_clean_domain',

			// W3 Total Cache.
			'w3tc_flush_all',

			// SGF plugin font cache delete.
			'sgf/after_delete_cache',
		];

		foreach ($hooks as $hook) {
			add_action($hook, [$this, 'empty']);
		}
	}

	/**
	 * Get all the debloat cache transients.
	 *
	 * @return array
	 */
	public function get_transients()
	{
		global $wpdb;

		return (array) $wpdb->get_results(
			"SELECT `option_name` FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_debloat_sheet_cache_%'",
			ARRAY_A
		);
	}

	/**
	 * Delete all the debloat cache transients.
	 *
	 * @return void
	 */
	protected function delete_transients()
	{
		foreach ($this->get_transients() as $transient) {
			$transient = str_replace('_transient_', '', $transient['option_name']);
			\delete_transient($transient);
		}
	}

	/**
	 * Delete all types of caches.
	 *
	 * @return void
	 */
	public function empty()
	{
		// Already clearing the caches. Needed as we hook into plugins clear methods,
		// but also call them ourselves on cache clear. 
		if ($this->deleting) {
			return;
		}

		// One of the hooks set via register_clear_hooks() may fire.
		$this->deleting = true;

		$this->delete_transients();

		// Delete files cache.
		Plugin::file_cache()->delete_cache('js');
		Plugin::file_cache()->delete_cache('css');

		// Clear cache plugins.
		$this->empty_cache_plugins();

		$this->deleting = false;
	}

	/**
	 * Empty external caches from plugins and hosts.
	 *
	 * @return void
	 */
	protected function empty_cache_plugins()
	{
		// WP Super Cache.
		if (function_exists('wp_cache_clear_cache')) {
			wp_cache_clear_cache(
				is_multisite() ? get_current_blog_id() : 0
			);
		}

		// W3 Total Cache.
		if (function_exists('w3tc_pgcache_flush')) {
			w3tc_pgcache_flush();
		}

		// WP Rocket.
		if (function_exists('rocket_clean_domain')) {
			rocket_clean_domain();
		}

		// WP Fastest Cache.
		if (function_exists('wpfc_clear_all_cache')) {
			wpfc_clear_all_cache();
		}

		// Swift Performance plugin.
		if (class_exists('\Swift_Performance_Cache') && is_callable(['\Swift_Performance_Cache', 'clear_all_cache'])) {
			\Swift_Performance_Cache::clear_all_cache();
		}
		
		// LiteSpeed Cache.
		if (class_exists('\LiteSpeed_Cache_API') && is_callable(['\LiteSpeed_Cache_API', 'purge_all'])) {
			\LiteSpeed_Cache_API::purge_all();
		}

		// Cache Enabler.
		if (class_exists('\Cache_Enabler') && is_callable(['\Cache_Enabler', 'clear_total_cache'])) {
			\Cache_Enabler::clear_total_cache();
		}

		// Comet cache.
		if (class_exists('\comet_cache') && is_callable(['\comet_cache', 'clear'])) {
			\comet_cache::clear();
		}

		// RT Nginx Helper plugin.
		if (defined('NGINX_HELPER_BASENAME')) {
			do_action('rt_nginx_helper_purge_all');
		}

		// Hummingbird 
		if (class_exists('\Hummingbird\WP_Hummingbird') && is_callable(['\Hummingbird\WP_Hummingbird', 'flush_cache'])) {
			\Hummingbird\WP_Hummingbird::flush_cache();
		}

		// Pagely.
		if (class_exists('\PagelyCachePurge') && is_callable(['\PagelyCachePurge', 'purgeAll'])) {
			\PagelyCachePurge::purgeAll();
		}

		// WPEngine
		if (class_exists('\WpeCommon')) {
			is_callable(['\WpeCommon', 'purge_memcached']) && \WpeCommon::purge_memcached();
			is_callable(['\WpeCommon', 'purge_varnish_cache']) && \WpeCommon::purge_varnish_cache();
		}

		// SiteGround.
		if (function_exists('sg_cachepress_purge_cache')) {
			sg_cachepress_purge_cache();
		}
	}
}