<?php
namespace WPDRMS\ASP\Updates;

use WPDRMS\PluginCore\Interfaces\Registrable;

if ( !defined('ABSPATH') ) {
	die('-1');
}

class UpgradeGuard implements Registrable {

	public function register(): void {
		add_filter('upgrader_pre_install', [ $this, 'preInstall' ], 1, 2);
	}

	public function deregister(): void {
		remove_filter('upgrader_pre_install', [ $this, 'preInstall' ], 1);
	}

	/**
	 * Fires just before the plugin package is extracted and files are replaced.
	 * Sweeps $wp_filter and removes every callback whose object belongs to the
	 * WPDRMS\ namespace, so cleanup hooks (e.g. delete_attachment) cannot trigger
	 * callbacks that reference classes which may not exist in the incoming version.
	 *
	 * Triggers for type=plugin to cover both auto-updates (plugin key present) and
	 * manual zip uploads (no plugin key, action=install).
	 *
	 * @param true|\WP_Error       $response
	 * @param array<string, mixed> $hookExtra
	 * @return true|\WP_Error
	 */
	public function preInstall( $response, array $hookExtra ) {
		if ( ( $hookExtra['type'] ?? '' ) !== 'plugin' ) {
			return $response;
		}

		global $wp_filter;
		foreach ( $wp_filter as $hook_name => $wp_hook ) {
			foreach ( $wp_hook->callbacks as $priority => $pri_data ) {
				foreach ( $pri_data as $cb => $cb_data ) {
					if (
						is_array($cb_data['function']) &&
						isset($cb_data['function'][0]) &&
						is_object($cb_data['function'][0]) &&
						strncmp(get_class($cb_data['function'][0]), 'WPDRMS\\', 7) === 0
					) {
						unset($wp_filter[ $hook_name ]->callbacks[ $priority ][ $cb ]);
					}
				}
			}
		}

		return $response;
	}
}
