<?php
/**
 * Filtre le transient core update pour cibler une version précise.
 *
 * @package CVS
 * @license GPL-2.0-or-later
 */

defined( 'ABSPATH' ) || exit;

class CVS_Core_Switch {

	/** @var CVS_Plugin */
	private $plugin;

	public function __construct( CVS_Plugin $plugin ) {
		$this->plugin = $plugin;
	}

	public function init() {
		add_filter( 'site_transient_update_core', array( $this, 'filter_update_core' ) );
		add_action( 'upgrader_process_complete', array( $this, 'on_core_upgraded' ), 10, 2 );

		if ( ! is_admin() ) {
			return;
		}

		$target = CVS_Settings::sanitize_version( $this->plugin->settings->get( 'target_version' ) );
		if ( $target ) {
			add_filter( 'pre_site_option_update_core', '__return_null' );
			if ( $this->plugin->settings->get( 'block_auto_core_updates' ) ) {
				add_filter( 'allow_major_auto_core_updates', '__return_false' );
				add_filter( 'allow_minor_auto_core_updates', '__return_false' );
				add_filter( 'auto_update_core', '__return_false' );
			}
			add_action( 'load-update-core.php', array( $this, 'update_core_admin_notice' ) );
		}
	}

	public function update_core_admin_notice() {
		if ( ! current_user_can( 'update_core' ) ) {
			return;
		}
		$target  = CVS_Settings::sanitize_version( $this->plugin->settings->get( 'target_version' ) );
		$current = get_bloginfo( 'version' );
		if ( ! $target || version_compare( $current, $target, '==' ) ) {
			return;
		}
		add_action(
			'admin_notices',
			function () use ( $target, $current ) {
				echo '<div class="notice notice-info"><p>';
				printf(
					/* translators: 1: current version, 2: target version */
					esc_html__( 'Core Version Switcher: you are on %1$s — use Reinstall below to switch to %2$s.', 'core-version-switcher-by-volade' ),
					esc_html( $current ),
					esc_html( $target )
				);
				echo '</p></div>';
			}
		);
	}

	/**
	 * @param object|false $updates
	 * @return object
	 */
	public function filter_update_core( $updates ) {
		$target = CVS_Settings::sanitize_version( $this->plugin->settings->get( 'target_version' ) );
		if ( ! $target ) {
			return $updates;
		}

		$current = get_bloginfo( 'version' );
		if ( version_compare( $current, $target, '==' ) ) {
			return $updates;
		}

		if ( ! is_object( $updates ) ) {
			$updates = new stdClass();
		}
		if ( ! isset( $updates->updates ) || ! is_array( $updates->updates ) ) {
			$updates->updates = array();
		}

		if ( empty( $updates->version_checked ) ) {
			$updates->version_checked = $current;
		}

		$package = $this->plugin->settings->build_download_url( $target );
		if ( ! $package ) {
			return $updates;
		}

		$update = (object) array(
			'response'      => 'upgrade',
			'download'      => $package,
			'locale'        => get_locale(),
			'packages'      => (object) array(
				'full'        => $package,
				'no_content'  => '',
				'new_bundled' => '',
				'partial'     => '',
				'rollback'    => '',
			),
			'current'       => $target,
			'version'       => $target,
			'php_version'   => phpversion(),
			'mysql_version' => $GLOBALS['wpdb']->db_version(),
		);

		$updates->updates[0]      = $update;
		$updates->last_checked    = time();
		$updates->version_checked = $current;

		return $updates;
	}

	/**
	 * @param WP_Upgrader $upgrader
	 * @param array       $options
	 */
	public function on_core_upgraded( $upgrader, $options ) {
		unset( $upgrader );
		if ( empty( $options['type'] ) || 'core' !== $options['type'] ) {
			return;
		}

		$target  = CVS_Settings::sanitize_version( $this->plugin->settings->get( 'target_version' ) );
		$current = get_bloginfo( 'version' );

		$from = CVS_Settings::sanitize_version( get_option( CVS_Settings::PREVIOUS_VERSION_KEY, '' ) );
		if ( ! $from && ! empty( $options['version'] ) ) {
			$from = CVS_Settings::sanitize_version( $options['version'] );
		}

		$this->plugin->settings->append_log(
			array(
				'action'  => 'core_switch',
				'from'    => $from,
				'to'      => $current,
				'target'  => $target,
				'user_id' => get_current_user_id(),
			)
		);

		CVS_Checksums::verify_install( $current, $this->plugin->settings->get_package_locale() );
		CVS_Email::notify_switch( $from, $current, get_current_user_id() );

		if ( $target && version_compare( $current, $target, '==' ) && $this->plugin->has_feature( 'auto_clear_target' ) ) {
			$this->plugin->settings->clear_target();
		}
	}
}
