<?php
/**
 * Core: Plugin Bootstrap
 *
 * @package     AffiliateWP PayPal Payouts
 * @subpackage  Core
 * @copyright   Copyright (c) 2021, Sandhills Development, LLC
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       1.3
 */

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;

/**
 * Main plugin bootstrap.
 *
 * @since 1.0
 */
final class AffiliateWP_PayPal_Payouts {

	/** Singleton *************************************************************/

	/**
	 * Main plugin instance.
	 *
	 * @since 1.0
	 * @var   AffiliateWP_PayPal_Payouts
	 * @static
	 */
	private static $instance;

	/**
	 * Plugin loader file.
	 *
	 * @since 1.3
	 * @var   string
	 */
	private $file = '';

	/**
	 * The version number.
	 *
	 * @since 1.0
	 * @var   string
	 */
	private $version = '1.4';

	/**
	 * Main AffiliateWP_PayPal_Payouts Instance
	 *
	 * Insures that only one instance of AffiliateWP_PayPal_Payouts exists in memory at any one
	 * time. Also prevents needing to define globals all over the place.
	 *
	 * @since 1.0
	 * @static
	 *
	 * @param string $file Path to the main plugin file.
	 * @return \AffiliateWP_PayPal_Payouts The one true bootstrap instance.
	 */
	public static function instance( $file = '' ) {
		if ( ! isset( self::$instance ) && ! ( self::$instance instanceof AffiliateWP_PayPal_Payouts ) ) {
			self::$instance = new AffiliateWP_PayPal_Payouts;
			self::$instance->file = $file;

			self::$instance->setup_constants();
			self::$instance->load_textdomain();
			self::$instance->includes();
			self::$instance->init();

		}
		return self::$instance;
	}

	/**
	 * Throw error on object clone
	 *
	 * The whole idea of the singleton design pattern is that there is a single
	 * object therefore, we don't want the object to be cloned.
	 *
	 * @since 1.0
	 * @access protected
	 * @return void
	 */
	public function __clone() {
		// Cloning instances of the class is forbidden
		_doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'affwp-paypal-payouts' ), '1.0' );
	}

	/**
	 * Disable unserializing of the class
	 *
	 * @since 1.0
	 * @access protected
	 * @return void
	 */
	public function __wakeup() {
		// Unserializing instances of the class is forbidden
		_doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'affwp-paypal-payouts' ), '1.0' );
	}

	/**
	 * Sets up plugin constants.
	 *
	 * @since 1.3
	 */
	private function setup_constants() {
		// Plugin version
		if ( ! defined( 'AFFWP_PP_VERSION' ) ) {
			define( 'AFFWP_PP_VERSION', $this->version );
		}

		// Plugin Folder Path
		if ( ! defined( 'AFFP_PP_PLUGIN_DIR' ) ) {
			define( 'AFFWP_PP_PLUGIN_DIR', plugin_dir_path( $this->file ) );
		}

		// Plugin Folder URL
		if ( ! defined( 'AFFWP_PP_PLUGIN_URL' ) ) {
			define( 'AFFWP_PP_PLUGIN_URL', plugin_dir_url( $this->file ) );
		}

		// Plugin Root File
		if ( ! defined( 'AFFWP_PP_PLUGIN_FILE' ) ) {
			define( 'AFFWP_PP_PLUGIN_FILE', $this->file );
		}
	}

	/**
	 * Loads the plugin language files
	 *
	 * @access public
	 * @since 1.0
	 * @return void
	 */
	public function load_textdomain() {

		// Set filter for plugin's languages directory
		$lang_dir = dirname( plugin_basename( $this->file ) ) . '/languages/';
		$lang_dir = apply_filters( 'affwp_stripe_languages_directory', $lang_dir );

		// Traditional WordPress plugin locale filter
		$locale   = apply_filters( 'plugin_locale',  get_locale(), 'affwp-paypal-payouts' );
		$mofile   = sprintf( '%1$s-%2$s.mo', 'affwp-paypal-payouts', $locale );

		// Setup paths to current locale file
		$mofile_local  = $lang_dir . $mofile;
		$mofile_global = WP_LANG_DIR . '/affwp-paypal-payouts/' . $mofile;

		if ( file_exists( $mofile_global ) ) {
			// Look in global /wp-content/languages/affwp-paypal-payouts/ folder
			load_textdomain( 'affwp-paypal-payouts', $mofile_global );
		} elseif ( file_exists( $mofile_local ) ) {
			// Look in local /wp-content/plugins/affwp-paypal-payouts/languages/ folder
			load_textdomain( 'affwp-paypal-payouts', $mofile_local );
		} else {
			// Load the default language files
			load_plugin_textdomain( 'affwp-paypal-payouts', false, $lang_dir );
		}
	}

	/**
	 * Include required files
	 *
	 * @access private
	 * @since 1.0
	 * @return void
	 */
	private function includes() {

		if ( is_admin() ) {
			require_once AFFWP_PP_PLUGIN_DIR . 'admin/class-paypal-api.php';
			require_once AFFWP_PP_PLUGIN_DIR . 'admin/class-paypal-masspay.php';
			require_once AFFWP_PP_PLUGIN_DIR . 'admin/payouts.php';
			require_once AFFWP_PP_PLUGIN_DIR . 'admin/referrals.php';
			require_once AFFWP_PP_PLUGIN_DIR . 'admin/settings.php';
		}

	}

	/**
	 * Add in our filters to affect affiliate rates
	 *
	 * @access private
	 * @since 1.0
	 * @return void
	 */
	private function init() {

		if( is_admin() ) {
			self::$instance->updater();
		}

	}


	/**
	 * Gets the Stripe API keys
	 *
	 * @access public
	 * @since 1.0
	 * @return array
	 */
	public function get_api_credentials() {

		$payout_mode = affiliate_wp()->settings->get( 'paypal_payout_mode', 'masspay' );
		$mode        = $this->is_test_mode() ? 'test' : 'live';

		if( 'api' == $payout_mode ) {

			$creds = array(
				'client_id' => affiliate_wp()->settings->get( 'paypal_' . $mode . '_client_id', '' ),
				'secret'    => affiliate_wp()->settings->get( 'paypal_' . $mode . '_secret', '' ),
			);

		} else {

			$creds = array(
				'username'  => affiliate_wp()->settings->get( 'paypal_' . $mode . '_username', '' ),
				'password'  => affiliate_wp()->settings->get( 'paypal_' . $mode . '_password', '' ),
				'signature' => affiliate_wp()->settings->get( 'paypal_' . $mode . '_signature', '' )
			);

		}

		return $creds;
	}

	/**
	 * Checks if we have API credentails
	 *
	 * @access public
	 * @since 1.0
	 * @return bool
	 */
	public function has_api_credentials() {

		$ret         = true;
		$payout_mode = affiliate_wp()->settings->get( 'paypal_payout_mode', 'masspay' );
		$creds       = $this->get_api_credentials();

		if( 'api' == $payout_mode ) {

			if( empty( $creds['client_id'] ) ) {
				$ret = false;
			}

			if( empty( $creds['secret'] ) ) {
				$ret = false;
			}

		} else {

			if( empty( $creds['username'] ) ) {
				$ret = false;
			}

			if( empty( $creds['password'] ) ) {
				$ret = false;
			}

			if( empty( $creds['signature'] ) ) {
				$ret = false;
			}

		}

		return $ret;
	}

	/**
	 * Determines if the user has at least version 2.4 of AffiliateWP.
	 *
	 * @since 1.2.1
	 *
	 * @return bool True if AffiliateWP v2.4 or newer, false otherwise.
	 */
	public function has_2_4() {

		$met = false;

		if ( version_compare( AFFILIATEWP_VERSION, '2.3.5', '>' ) ) {
			$met = true;
		}

		return $met;
	}

	/**
	 * Determines if we are in test mode
	 *
	 * @access public
	 * @since 1.0
	 * @return bool
	 */
	public function is_test_mode() {

		return (bool) affiliate_wp()->settings->get( 'paypal_test_mode', false );
	}


	/**
	 * Sets up the plugin updater class
	 *
	 * @access private
	 * @since 1.0
	 * @return void
	 */
	public function updater() {

		if( class_exists( 'AffWP_AddOn_Updater' ) ) {
			$updater = new AffWP_AddOn_Updater( 345, $this->file, $this->version );
		}
	}

	/**
	 * Displays an error message if PHP version is below 5.3
	 *
	 * @access private
	 * @since 1.1
	 * @return void
	 */
	public function php_version_notice() {
		echo '<div class="error"><p>' . __( 'Your version of PHP is below the minimum version of PHP required by AffiliateWP - PayPal Payouts. Version 5.3 or later is required.', 'affwp-paypal-payouts' ) . '</p></div>';
	}

}

/**
 * The main function responsible for returning the one true AffiliateWP_PayPal_Payouts
 * Instance to functions everywhere.
 *
 * Use this function like you would a global variable, except without needing
 * to declare the global.
 *
 * Example: <?php $AffiliateWP_PayPal_Payouts = affiliate_wp_paypal(; ?>
 *
 * @since 1.0
 * @return \AffiliateWP_PayPal_Payouts The one true AffiliateWP_PayPal_Payouts Instance
 */
function affiliate_wp_paypal() {
	return AffiliateWP_PayPal_Payouts::instance();
}
