<?php
/**
 * Activation handler.
 *
 * @package SubmissionInbox
 */

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

require_once __DIR__ . '/Lifecycle/SiteProvisioner.php';

/**
 * Handles plugin activation and multisite provisioning.
 */
class SUBIN_Activator {
	/**
	 * Run activation tasks for one site or the whole network.
	 *
	 * @param bool $network_wide Whether activation is network-wide.
	 * @return void
	 */
	public static function activate( $network_wide = false ) {
		if ( is_multisite() && $network_wide ) {
			$result = \SUBIN\Lifecycle\SiteProvisioner::for_each_site(
				array( '\SUBIN\Lifecycle\SiteProvisioner', 'provision_current_site' )
			);
		} else {
			$result = \SUBIN\Lifecycle\SiteProvisioner::provision_current_site();
		}

		if ( is_wp_error( $result ) ) {
			self::fail_activation( $result, $network_wide );
		}
	}

	/**
	 * Register hooks needed to provision and clean up future multisite sites.
	 *
	 * @return void
	 */
	public static function register_multisite_hooks() {
		if ( ! is_multisite() ) {
			return;
		}

		add_action( 'wp_initialize_site', array( __CLASS__, 'provision_new_site' ), 20, 2 );
		add_action( 'wp_uninitialize_site', array( __CLASS__, 'remove_deleted_site' ), 10, 1 );
	}

	/**
	 * Provision a newly created site when the plugin is network active.
	 *
	 * @param WP_Site $new_site New site.
	 * @param array   $args Initialization arguments.
	 * @return void
	 */
	public static function provision_new_site( $new_site, $args = array() ) {
		unset( $args );

		if ( ! self::is_network_active() || ! $new_site instanceof WP_Site ) {
			return;
		}

		\SUBIN\Lifecycle\SiteProvisioner::for_site(
			absint( $new_site->blog_id ),
			array( '\SUBIN\Lifecycle\SiteProvisioner', 'provision_current_site' )
		);
	}

	/**
	 * Remove plugin-owned tables when WordPress permanently removes a site.
	 *
	 * @param WP_Site $old_site Site being removed.
	 * @return void
	 */
	public static function remove_deleted_site( $old_site ) {
		if ( ! $old_site instanceof WP_Site ) {
			return;
		}

		\SUBIN\Lifecycle\SiteProvisioner::for_site(
			absint( $old_site->blog_id ),
			function () {
				return \SUBIN\Lifecycle\SiteProvisioner::remove_current_site( true );
			}
		);
	}

	/**
	 * Whether this plugin is active for the whole network.
	 *
	 * @return bool
	 */
	private static function is_network_active() {
		if ( ! defined( 'SUBIN_PLUGIN_FILE' ) ) {
			return false;
		}

		if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		return is_plugin_active_for_network( plugin_basename( SUBIN_PLUGIN_FILE ) );
	}

	/**
	 * Abort activation instead of allowing a partially initialized schema.
	 *
	 * @param WP_Error $error Activation error.
	 * @param bool     $network_wide Whether activation is network-wide.
	 * @return void
	 */
	private static function fail_activation( WP_Error $error, $network_wide ) {
		if ( defined( 'SUBIN_PLUGIN_FILE' ) && function_exists( 'deactivate_plugins' ) ) {
			deactivate_plugins( plugin_basename( SUBIN_PLUGIN_FILE ), true, (bool) $network_wide );
		}

		wp_die(
			esc_html(
				sprintf(
					/* translators: %s: database activation error. */
					__( 'Submission Inbox could not be activated: %s', 'submission-inbox' ),
					$error->get_error_message()
				)
			),
			esc_html__( 'Submission Inbox activation failed', 'submission-inbox' ),
			array( 'back_link' => true )
		);
	}
}

SUBIN_Activator::register_multisite_hooks();
