<?php
/**
 * BaseCloud Boost — Hosting Environment Detector
 *
 * @package BaseCloud\Boost\Compatibility
 */

declare( strict_types=1 );

namespace BaseCloud\Boost\Compatibility;

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

/**
 * Detects the hosting environment and applies host-specific tweaks.
 */
class Host_Detector {

	/** @var string Detected host slug. */
	private string $host = 'generic';

	/**
	 * Boot host-specific compatibility.
	 *
	 * @return void
	 */
	public function boot(): void {
		$this->host = $this->detect();
		$this->apply_tweaks();
	}

	/**
	 * Detect the current hosting environment.
	 *
	 * @return string Host slug.
	 */
	public function detect(): string {
		// WP Engine.
		if ( defined( 'WPE_APIKEY' ) || isset( $_SERVER['IS_WPE'] ) ) {
			return 'wpengine';
		}

		// Kinsta.
		if ( isset( $_SERVER['KINSTA_CACHE_ZONE'] ) || defined( 'KINSTA_CACHE_ZONE' ) ) {
			return 'kinsta';
		}

		// Flywheel / Local.
		if ( isset( $_SERVER['FLYWHEEL_CONFIG_DIR'] ) ) {
			return 'flywheel';
		}

		// SiteGround.
		if ( function_exists( 'sg_cachepress_purge_cache' ) || defined( 'SG_CachePress_Supercacher' ) ) {
			return 'siteground';
		}

		// Pagely.
		if ( defined( 'PAGELY_CUSTOMER_ID' ) ) {
			return 'pagely';
		}

		// Pantheon.
		if ( isset( $_ENV['PANTHEON_ENVIRONMENT'] ) ) {
			return 'pantheon';
		}

		// Cloudways.
		if ( isset( $_SERVER['cw_anonymous_id'] ) || defined( 'CLOUDWAYS_HOST' ) ) {
			return 'cloudways';
		}

		// Pressable.
		if ( isset( $_SERVER['PRESSABLE_SITE_NAME'] ) ) {
			return 'pressable';
		}

		// WP.com VIP.
		if ( defined( 'WPCOM_IS_VIP_ENV' ) ) {
			return 'wpcomvip';
		}

		// Nginx server software.
		$software = strtolower( $_SERVER['SERVER_SOFTWARE'] ?? '' );
		if ( strpos( $software, 'nginx' ) !== false ) {
			return 'nginx';
		}

		// LiteSpeed.
		if ( strpos( $software, 'litespeed' ) !== false ) {
			return 'litespeed';
		}

		return 'generic';
	}

	/**
	 * Get the detected host slug.
	 *
	 * @return string
	 */
	public function get_host(): string {
		return $this->host;
	}

	/**
	 * Whether page caching should be disabled for this host
	 * (host has its own full-page cache).
	 *
	 * @return bool
	 */
	public function host_has_page_cache(): bool {
		return in_array( $this->host, [ 'wpengine', 'kinsta', 'pagely', 'pantheon', 'wpcomvip' ], true );
	}

	/**
	 * Detect the environment now and report whether this host runs its own
	 * full-page cache (so Boost must not install its advanced-cache.php drop-in).
	 *
	 * Safe to call before boot() — used by the activator/upgrade routine.
	 *
	 * @return bool
	 */
	public function detect_has_page_cache(): bool {
		$this->host = $this->detect();
		return $this->host_has_page_cache();
	}

	/**
	 * Whether the current request is running on Cloudways (which puts Varnish in
	 * front of the app). Static so the Varnish integration can auto-enable its
	 * Cloudways purge without the user configuring anything. Mirrors the Cloudways
	 * branch of detect().
	 *
	 * @return bool
	 */
	public static function is_cloudways(): bool {
		return isset( $_SERVER['cw_anonymous_id'] ) || defined( 'CLOUDWAYS_HOST' );
	}

	/**
	 * Apply host-specific tweaks.
	 *
	 * @return void
	 */
	private function apply_tweaks(): void {
		switch ( $this->host ) {
			case 'wpengine':
				$this->tweak_wpengine();
				break;
			case 'kinsta':
				$this->tweak_kinsta();
				break;
			case 'siteground':
				$this->tweak_siteground();
				break;
			case 'litespeed':
				$this->tweak_litespeed();
				break;
		}
	}

	/**
	 * WP Engine: Disable our file-based page cache (WPE has its own).
	 *
	 * @return void
	 */
	private function tweak_wpengine(): void {
		add_filter( 'BCBOOST_page_cache_enabled', '__return_false' );
		add_action( 'BCBOOST_after_purge_all', static function (): void {
			if ( function_exists( 'wpe_cdn_purge_all' ) ) {
				wpe_cdn_purge_all();
			}
		} );
	}

	/**
	 * Kinsta: Disable file-based page cache, hook into Kinsta's purge.
	 *
	 * @return void
	 */
	private function tweak_kinsta(): void {
		add_filter( 'BCBOOST_page_cache_enabled', '__return_false' );
		add_action( 'BCBOOST_after_purge_all', static function (): void {
			if ( function_exists( 'kinsta_cache_purge_all' ) ) {
				kinsta_cache_purge_all();
			}
		} );
	}

	/**
	 * SiteGround: Purge SG cache alongside BCB cache.
	 *
	 * @return void
	 */
	private function tweak_siteground(): void {
		add_action( 'BCBOOST_after_purge_all', static function (): void {
			if ( function_exists( 'sg_cachepress_purge_cache' ) ) {
				sg_cachepress_purge_cache();
			}
		} );
	}

	/**
	 * LiteSpeed: Send a purge signal to LiteSpeed cache.
	 *
	 * @return void
	 */
	private function tweak_litespeed(): void {
		add_action( 'BCBOOST_after_purge_all', static function (): void {
			do_action( 'litespeed_purge_all' );
		} );
	}
}
