<?php
/**
 * Please see weepie-framework.php for more details.
 */

namespace WpieFw\Wpie;

use WpieFw\Wpie\WpieGlobals;
use WpieFw\Helpers\WpieMultisiteHelper;
use WpieFw\Helpers\WpieMiscHelper;

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

/**
 * WpieUpgrader Class
 *
 * @author $Author: Vincent Weber <weepie-plugins@outlook.com> $
 * @since 1.4.0
 */
final class WpieUpgrader
{
	/**
	 * The wp_options entry holding the WeePie Framework version
	 *
	 * @since 2.0.1
	 *
	 * @var string
	 */
	const OPTION_NAME_WPIEFW_VERSION = 'wpiefw_version';

	/**
	 * The wp_options entry holding the old WeePie Framework version
	 *
	 * @since 2.0.1
	 *
	 * @var string
	 */
	const OPTION_NAME_WPIEFW_VERSION_OLD = 'wpiefw_version_old';

	/**
	 * The wp_options entry holding the WeePie Framework active status
	 *
	 * @since 2.0.1
	 *
	 * @var string
	 */
	const OPTION_NAME_WPIEFW_ACTIVE = 'wpiefw_active';

	/**
	 * The wp_options entry holding the WeePie Framework Plugin version
	 *
	 * @since 2.0.1
	 *
	 * @var string
	 */
	const OPTION_NAME_TMPL_PLUGIN_VERSION = '%s_version';

	/**
	 * WpieGlobals instance
	 *
	 * @since 1.4.0
	 *
	 * @var WpieGlobals
	 */
	private $globals;

	/**
	 * Flaf if params have been set
	 *
	 * @since 2.0.1
	 *
	 * @var bool
	 */
	private $paramsSet = false;

	/**
	 * Flag if plugin is network activated
	 *
	 * @since 2.0.1
	 *
	 * @var bool
	 */
	public $networkActivated = false;

	/**
	 * Flag if plugin has been activated in the previous request
	 *
	 * @since 2.0.3
	 *
	 * @var bool
	 */
	public $isActivated = false;

	/**
	 * Flag if plugin is being upgraded
	 *
	 * @since 2.0.1
	 *
	 * @var bool
	 */
	public $upgrading = false;

	/**
	 * Flag if WeePie Framework is being upgraded
	 *
	 * @since 2.0.1
	 *
	 * @var bool
	 */
	public $upgradingWf = false;

	/**
	 * Old WeePie Framework version
	 *
	 * @since 2.0.1
	 *
	 * @var string
	 */
	public $versionWfOld = 0;

	/**
	 * Old plugin version
	 *
	 * @since 2.0.1
	 *
	 * @var string
	 */
	public $versionPluginOld = 0;

	/**
	 * Flag if verison has changed while not activating
	 *
	 * @since 2.0.1
	 *
	 * @var bool
	 */
	public $versionChangedSilently = false;

	/**
	 * Constructor
	 *
	 * @access public
	 *
	 * @param WpieGlobals $globals
	 *
	 * @since 1.4.0
	 */
	public function __construct( WpieGlobals $globals )
	{
		$this->globals = $globals;

		if( function_exists( 'is_plugin_active_for_network' ) ) {
		    $this->networkActivated = is_plugin_active_for_network( $this->globals->get( 'pluginFile' ) ) ||
		                              WpieMultisiteHelper::isActivatingPluginForNework( $this->globals->get( 'pluginFile' ) );
		}

		$this->isActivated = WpieMiscHelper::isActivated() &&
		                     WpieMultisiteHelper::getOption( $this->globals->get( 'optionActivating' ), false, $this->networkActivated );
	}

	/**
	 * Set all params
	 *
	 * @since 2.0.1
	 *
	 * @return \WpieFw\Wpie\WpieUpgrader
	 */
	public function setParams()
	{
		// WeePie Framework old version
		$this->versionWfOld = WpieMultisiteHelper::getOption( self::OPTION_NAME_WPIEFW_VERSION, 0, $this->networkActivated );
		if( false != $this->versionWfOld ) {
			// flag if WeePie Framework is being upgraded
			$this->upgradingWf = version_compare(
					$this->versionWfOld,
					$this->globals->get( 'versionWf' ),
					'<'
					);
		}

		// Plugin old version
		$this->versionPluginOld = WpieMultisiteHelper::getOption( sprintf( self::OPTION_NAME_TMPL_PLUGIN_VERSION, $this->globals->nameSpace ), 0, $this->networkActivated );
		if( false != $this->versionPluginOld ) {
			// Flag if plugin is being upgraded
			$this->upgrading = version_compare(
					$this->versionPluginOld,
					$this->globals->get( 'version' ),
					'<'
					);
		}

		// Flag if the verion changed, while not activly activating the plugin
		$this->versionChangedSilently = ( $this->upgrading && !$this->globals->get( 'isActivating') );

		// force network activation params in wp_sitemeta table
		if( $this->versionChangedSilently && is_network_admin() ) {
			$this->networkActivated = true;
		}

		// Indicate params have been set
		$this->paramsSet = true;

		return $this;
	}

	/**
	 * Persist data
	 *
	 * @uses WpieMultisiteHelper::updateOption()
	 *
	 * @since 2.0.1
	 *
	 * @return \WpieFw\Wpie\WpieUpgrader
	 */
	public function persistData()
	{
		if( !$this->paramsSet ) {
			$this->setParams();
		}

		if( $this->upgradingWf ) {
			WpieMultisiteHelper::updateOption( self::OPTION_NAME_WPIEFW_VERSION_OLD, $this->versionWfOld, $this->networkActivated );
		}

		// set the new WeePie Framework version number and flag Framework is active
		WpieMultisiteHelper::updateOption( self::OPTION_NAME_WPIEFW_VERSION, $this->globals->get( 'versionWf' ), $this->networkActivated );
		WpieMultisiteHelper::updateOption( self::OPTION_NAME_WPIEFW_ACTIVE, '1', $this->networkActivated );
		WpieMultisiteHelper::updateOption( sprintf( self::OPTION_NAME_TMPL_PLUGIN_VERSION, $this->globals->nameSpace ), $this->globals->get( 'version' ), $this->networkActivated );

		return $this;
	}

	/**
	 * Has the verion changed silently
	 *
	 * @since 2.0.1
	 *
	 * @return bool
	 */
	public function hasVersionChangedSilently()
	{
		if( !$this->paramsSet ) {
			$this->setParams();
		}

		return $this->versionChangedSilently;
	}

	/**
	 * Do upgrade dependend logic
	 *
	 * @access public
	 *
	 * @since 1.2

	 * @param bool $networkWide
	 */
	public function doUpgradeDependendLogic( $networkWide )
	{
		$pluginPath = $this->globals->get( 'pluginPath' );
		$upgradeFile = $pluginPath . '/upgrade.php';

		if( 0 === $this->globals->get( 'versionOld' ) ) {
			return;
		} elseif( file_exists( $upgradeFile ) ) {
			@include_once $upgradeFile;
		} else {
			return;
		}

		// Dynamic function name based on WeePie Framework new version
		$function = sprintf( '%s_wpiefw_upgrade_%s', $this->globals->nameSpace, str_replace( ['.','-'], ['', '_'], $this->globals->get( 'versionWf' ) ) );

		if( function_exists( $function ) ) {
			call_user_func( $function, $networkWide );
		}

		do_action(  $this->globals->nameSpace . '_wpiefw_upgrade_logic',
				$this->globals->get( 'versionOld' ),
				$this->globals->get( 'version' ),
				$this->globals->get( 'versionWfOld' ),
				$this->globals->get( 'versionWf' ),
				$networkWide
				);
	}

	/**
	 * Handle notices added by the plugin
	 *
	 * @uses get_transient()
	 * @uses delete_transient()
	 * @uses \WpieFw\Notices\WpieNotices::add()
	 *
	 * @return \WpieFw\Wpie\WpieUpgrader
	 */
	public function pluginNotices()
	{
		// Show an upgrade message if one has been set
		if( !$this->globals->get( 'isActivating' ) && $msg = get_transient( $this->globals->nameSpace . '_upgrade_msg' ) ) {
			\WpieFw\Notices\WpieNotices::add( $this->globals->nameSpace, $msg, 'info' );

			add_action( $this->globals->nameSpace . '_after_init_settings_page', function( \WpieFw\Settings\WpieSettingsProcessor $processor ) {
				if( $processor->settingsPage->onSettingsPage ) {
					delete_transient( $this->globals->nameSpace . '_upgrade_msg' );
				}
			} );
		}

		return $this;
	}
}