<?php
/**
 * Tracking functions for reporting plugin usage to the Engine site for users that have opted in
 *
 * @package     Gutentor
 * @subpackage  Admin
 * @since       3.2.1
 */

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

/**
 * Agent Usage tracking
 *
 * @since  3.2.1
 * @return void
 */
class Gutentor_Tracking {

	/**
	 * @access private
	 */
	private $slug                 = '';
	private $secret_opt_key       = '';
	private $last_send_opt_key    = '';
	private $hide_notice_opt_key  = '';
	private $agents_opt_key       = '';
	private $agent_active_opt_key = '';
	private $data;
	private $api_url    = '';
	private $remote_url = '';
	private $version    = '';

	/**
	 * Get things going
	 * allow-tracking is set from $this->get_opt_data()
	 * Other from opt key
	 *
	 * @since  3.2.1
	 * @return void
	 */
	public function __construct() {

		/*Changed with the plugin*/
		$this->remote_url = trailingslashit( 'https://tracking.acmeit.org' );
		$this->slug       = GUTENTOR_PLUGIN_NAME;
		$this->version    = '1.0.0';
		/*Changed with the plugin end*/

		$this->secret_opt_key       = 'agent_secret_key';
		$this->last_send_opt_key    = 'agent_last_send';
		$this->hide_notice_opt_key  = 'agent_hide_notice';
		$this->agent_active_opt_key = 'is_active_this_track';

		$this->agents_opt_key = 'agent_' . md5( $this->remote_url );/*unique per remote url*/

		$this->init();
	}

	/**
	 * Set up WordPress hooks.
	 *
	 * @since  3.2.1
	 * @return void
	 */
	public function init() {

		add_action( 'init', array( $this, 'schedule_send' ) );
		add_action( 'gutentor_set_settings_options', array( $this, 'is_do_post' ) );
		add_action( 'admin_init', array( $this, 'do_agents' ) );
		add_action( 'admin_init', array( $this, 'do_show_tracking_notice' ) );
		add_action( 'admin_notices', array( $this, 'admin_notice' ) );
	}

	/**
	 * Update agents.
	 * Run once in the lifetime.
	 *
	 * @since  3.2.1
	 * @return void
	 */
	public function do_agents() {

		$installed_agents = get_option( $this->agents_opt_key, array() );
		if ( isset( $installed_agents[ $this->slug ] ) ) {
			return;
		}

		$installed_agents[ $this->slug ] = $this->version;

		$active_agent = $this->get_opt_data( $this->agent_active_opt_key, '' );

		if ( ! $active_agent ) {
			$active_agent = $this->slug;
		} elseif ( is_array( $installed_agents ) && ! empty( $installed_agents ) ) {
				$highest_ver = $this->version;
			foreach ( $installed_agents as $agent => $agent_ver ) {
				if ( version_compare( $agent_ver, $highest_ver ) > 0 ) {
					$highest_ver  = $agent_ver;
					$active_agent = $agent;
				}
			}
		}

		gutentor_add_installed_time();

		// register this agent locally.
		$this->update_opt_data( $this->agent_active_opt_key, $active_agent );

		// register agent data globally.
		update_option( $this->agents_opt_key, $installed_agents );
	}

	/**
	 * Is this active agent
	 *
	 * @since  3.2.1
	 * @return boolean
	 */
	private function is_active_agent() {
		if ( $this->slug == $this->get_opt_data( $this->agent_active_opt_key ) ) {
			return true;
		}
		return false;
	}

	/**
	 * Update secret keyy
	 *
	 * @since  3.2.1
	 * @return void
	 */
	private function update_secret_key( $res ) {
		// get secret key from engine.
		$get_secret_key = json_decode( $res, true );
		$secret_key     = 'none';
		if ( $get_secret_key && is_array( $get_secret_key ) && isset( $get_secret_key['secret_key'] ) ) {
			$secret_key = $get_secret_key['secret_key'];
		}
		$this->update_opt_data( $this->secret_opt_key, sanitize_text_field( $secret_key ) );
	}

	/**
	 * Authorize this site to send data to engine.
	 * get secret key from engine
	 * run on agent activation.
	 *
	 * @since  3.2.1
	 * @return void
	 */
	public function do_handshake() {
		$secret_key = $this->get_opt_data( $this->secret_opt_key );

		if ( ! empty( $secret_key ) ) {
			// secret_key already exists.
			// do nothing.
			return;
		}

		// authenticate with engine.
		$this->api_url = $this->remote_url . 'wp-json/acme-udp-admin/v1/handshake';

		$get_secret_key = $this->do_post( true, true );

		$this->update_secret_key( $get_secret_key );
	}

	/**
	 * Default Options
	 *
	 * @return array
	 *
	 * @since  3.2.1
	 */
	private function default_options() {
		return array(
			'allow-tracking' => false,
		);
	}

	/**
	 * Get option.
	 *
	 * @since  3.2.1
	 * @return array
	 */
	private function get_opt_data( $key = '' ) {
		$advanced_import_options = json_decode( get_option( '__gutentor_helper_options' ), true );

		$advanced_import_default_options = $this->default_options();
		if ( ! empty( $key ) ) {
			if ( isset( $advanced_import_options[ $key ] ) ) {
				return $advanced_import_options[ $key ];
			}
			return isset( $advanced_import_default_options[ $key ] ) ? $advanced_import_default_options[ $key ] : '';
		} else {
			if ( ! is_array( $advanced_import_options ) ) {
				$advanced_import_options = array();
			}
			return array_merge( $advanced_import_default_options, $advanced_import_options );
		}
	}

	/**
	 * Update options.
	 *
	 * @since  3.2.1
	 * @return array
	 */
	private function update_opt_data( $key, $val ) {
		$helper_options = json_decode( get_option( '__gutentor_helper_options' ), true );
		if ( ! is_array( $helper_options ) ) {
			$helper_options = array();
		}
		$helper_options[ $key ] = $val;
		update_option(
			'__gutentor_helper_options',
			wp_json_encode( $helper_options )
		);
	}

	/**
	 * Gather data to send to engine.
	 *
	 * @since  3.2.1
	 * @return array
	 */
	private function get_data() {

		if ( ! class_exists( 'WP_Debug_Data' ) ) {
			include_once ABSPATH . 'wp-admin/includes/class-wp-debug-data.php';
		}

		// Ensure get_core_updates is available (needed by WP_Debug_Data::debug_data).
		if ( ! function_exists( 'get_core_updates' ) ) {
			include_once ABSPATH . 'wp-admin/includes/update.php';
		}

		$data = array();

		if ( method_exists( 'WP_Debug_Data', 'debug_data' ) && function_exists( 'get_core_updates' ) ) {
			$data['data'] = WP_Debug_Data::debug_data();
		} else {
			$data['data'] = array();
		}
		$data['admin_email'] = get_bloginfo( 'admin_email' );
		$user                = get_user_by( 'email', $data['admin_email'] );

		if ( $user && isset( $user->data->user_nicename ) ) {
			$data['nicename'] = $user->data->user_nicename;
		} else {
			$data['nicename'] = 'Unknown';
		}

		$data['site_url'] = get_bloginfo( 'url' );
		$data['version']  = get_bloginfo( 'version' );

		$data['sender'] = $this->slug;

		return $data;
	}

	/**
	 * Setup the data
	 *
	 * @access private
	 *
	 * @since  3.2.1
	 * @return void
	 */
	private function setup_data() {
		$data               = array();
		$data['agent_data'] = maybe_serialize( $this->get_data() );
		$data['secret_key'] = $this->get_opt_data( $this->secret_opt_key );
		$this->data         = $data;
	}

	/**
	 * Send the data to the Engine server
	 *
	 * @access public
	 *
	 * @param  bool $override If we should override the tracking setting.
	 * @param  bool $is_handshake If it is just handshake to get secret key.
	 *
	 * @since  3.2.1
	 * @return bool
	 */
	public function do_post( $override = false, $is_handshake = false ) {

		if ( ! $this->get_opt_data( 'allow-tracking' ) && ! $override ) {
			return false;
		}

		/*Send a maximum of once per week*/
		$last_send = $this->get_last_send();
		if ( is_numeric( $last_send ) && $last_send > strtotime( '-1 week' ) && ! $is_handshake ) {
			return false;
		}

		/*if this agent is not active agent*/
		if ( ! $this->is_active_agent() ) {
			return false;
		}

		if ( ! $is_handshake ) {
			$this->api_url = $this->remote_url . 'wp-json/acme-udp-admin/v1/process-data';
			$this->update_last_send();
		}

		$this->setup_data();
		$response = wp_remote_post(
			$this->api_url,
			array(
				'method'      => 'POST',
				'timeout'     => 45,
				'redirection' => 5,
				'httpversion' => '1.0',
				'blocking'    => true,
				'headers'     => array(),
				'body'        => $this->data,
			)
		);

		if ( $is_handshake ) {
			return wp_remote_retrieve_body( $response );
		} else {
			$is_secret_key = json_decode( wp_remote_retrieve_body( $response ), true );
			if ( is_array( $is_secret_key ) && isset( $is_secret_key['secret_key'] ) ) {
				$this->update_secret_key( wp_remote_retrieve_body( $response ) );
			}
		}
	}

	/**
	 * While user allow the tracking
	 *
	 * @since  3.2.1
	 * @return array
	 */
	public function is_do_post( $g_options ) {

		if ( isset( $g_options['allow_tracking'] ) && $g_options['allow_tracking'] == 1 ) {
			$this->do_post( true );
		}

		return $g_options;
	}

	/**
	 * When saving hide tracking notice.
	 *
	 * @return void
	 */
	public function do_show_tracking_notice() {

		$this->do_handshake();

		// listen for our activate button to be clicked
		if ( ! isset( $_GET[ esc_attr( $this->slug ) . '_tracking' ] ) ) {
			return;
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		/*Security check*/
		check_admin_referer( $this->slug );

		if ( 1 == $_GET[ esc_attr( $this->slug ) . '_tracking' ] ) {
			$this->update_opt_data( 'allow-tracking', true );
			$this->do_post( true );
		} else {
			$this->update_opt_data( 'allow-tracking', false );
		}

		$this->update_hide_tracking_notice( true );
	}

	/**
	 * Schedule a weekly tracking
	 *
	 * @return array|false|string
	 * @since  3.2.1
	 */
	public function schedule_send() {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Anti-hotlinking probe check, not processing form data.
		if ( isset( $_GET['acmeit_verify_user_secret_key_rand_3022'] ) ) {
			die( 'equal' );
		}
		if ( wp_doing_cron() ) {
			add_action( 'gutentor_weekly_scheduled_events', array( $this, 'do_post' ) );
		}
	}

	/**
	 * Update last send
	 *
	 * @since  3.2.1
	 * @return void
	 */
	public function update_last_send() {

		$this->update_opt_data( $this->last_send_opt_key, time() );
	}

	/**
	 * Get last send
	 *
	 * @since  3.2.1
	 * @return string
	 */
	public function get_last_send() {
		return $this->get_opt_data( $this->last_send_opt_key );
	}

	/**
	 * Update hide notice
	 *
	 * @since  3.2.1
	 * @return void
	 */
	public function update_hide_tracking_notice( $val = false ) {
		$this->update_opt_data( $this->hide_notice_opt_key, $val );
	}

	/**
	 * Get hide notice
	 *
	 * @since  3.2.1
	 * @return boolean
	 */
	public function get_hide_tracking_notice() {
		return $this->get_opt_data( $this->hide_notice_opt_key );
	}

	/**
	 * Check if we can show tracking notice to user.
	 *
	 * @since  3.2.1
	 * @return boolean
	 */
	public function can_show_notice() {

		if ( $this->get_opt_data( 'installed_time' ) > strtotime( '-3 day' ) ) {
			return false;
		}

		if ( $this->get_hide_tracking_notice() ) {
			return false;
		}
		if ( $this->get_opt_data( 'allow-tracking' ) ) {
			return false;
		}
		if ( ! current_user_can( 'manage_options' ) ) {
			return false;
		}
		/*if this agent is not active agent*/
		if ( ! $this->is_active_agent() ) {
			return false;
		}
		return true;
	}

	/**
	 * Get current admin page URL.
	 *
	 * Returns an empty string if it cannot generate a URL.
	 *
	 * @since 3.2.1
	 * @return string
	 */
	private function get_current_admin_url() {
		$uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
		$uri = preg_replace( '|^.*/wp-admin/|i', '', $uri );

		if ( ! $uri ) {
			return '';
		}

		return remove_query_arg( array( '_wpnonce' ), admin_url( $uri ) );
	}

	/**
	 * Display the admin notice to users.
	 *
	 * @return void
	 * @since  3.2.1
	 */
	public function admin_notice() {

		if ( ! $this->can_show_notice() ) {
			return;
		}
		global $current_user;

		$allow_url     = wp_nonce_url(
			add_query_arg(
				array(
					esc_attr( $this->slug ) . '_tracking' => 1,
				),
				$this->get_current_admin_url()
			),
			$this->slug
		);
		$not_allow_url = wp_nonce_url(
			add_query_arg(
				array(
					esc_attr( $this->slug ) . '_tracking' => 0,
				),
				$this->get_current_admin_url()
			),
			$this->slug
		);
		?>
		<div class="notice updated <?php echo esc_attr( $this->slug ); ?>-track-notice">
			<p style="float: left">
				<?php
				printf(
				/* Translators: %1$s current user display name. */
					esc_html__(
						'Howdy, %1$s! Allow Gutentor to anonymously track how this plugin is used and help us make the plugin better. No sensitive data is tracked.',
						'gutentor'
					),
					'<strong>' . esc_html( $current_user->display_name ) . '</strong>'
				);
				?>
			</p>


			<a href="<?php echo esc_url( $allow_url ); ?>" class="btn button-primary">
				<span><?php esc_html_e( 'Allow', 'gutentor' ); ?></span>
			</a>
			<a href="<?php echo esc_url( $not_allow_url ); ?>" class="btn button-link">
				<span><?php esc_html_e( 'Do not allow', 'gutentor' ); ?></span>
			</a>

		</div>

		<?php
	}
}
global $gutentor_tracking;
$gutentor_tracking = new Gutentor_Tracking();
