<?php
/**
 * This file contains a class for logging experiments in AWS.
 *
 * @package    Nelio_AB_Testing
 * @subpackage Nelio_AB_Testing/includes/utils
 * @since      5.0.0
 */

defined( 'ABSPATH' ) || exit;

/**
 * This class logs experiments in AWS.
 *
 * @package    Nelio_AB_Testing
 * @subpackage Nelio_AB_Testing/includes/utils
 * @since      5.0.0
 */
class Nelio_AB_Testing_Logger {

	/**
	 * Hooks into WordPress.
	 *
	 * @return void
	 * @since  5.0.0
	 */
	public function init() {

		add_action( 'nab_after_create_experiment', array( $this, 'log_experiment' ), 99 );
		add_action( 'nab_start_experiment', array( $this, 'log_experiment' ), 99 );
		add_action( 'nab_restart_experiment', array( $this, 'log_experiment' ), 99 );
		add_action( 'nab_pause_experiment', array( $this, 'log_experiment' ), 99 );
		add_action( 'nab_resume_experiment', array( $this, 'log_experiment' ), 99 );
		add_action( 'nab_stop_experiment', array( $this, 'log_experiment' ), 99 );
		add_action( 'nab_updated', array( $this, 'log_site' ) );
		add_action( 'nab_site_created', array( $this, 'log_site' ) );
		add_action( 'upgrader_process_complete', array( $this, 'maybe_log_site_on_upgrade' ), 10, 2 );
		add_action( 'update_option_home', array( $this, 'maybe_log_site_on_option_update' ), 10, 2 );
		add_action( 'update_option_timezone_string', array( $this, 'maybe_log_site_on_option_update' ), 10, 2 );
		add_action( 'update_option_gmt_offset', array( $this, 'maybe_log_site_on_option_update' ), 10, 2 );
		add_action( 'update_option_WPLANG', array( $this, 'maybe_log_site_on_option_update' ), 10, 2 );
	}

	/**
	 * Logs an experiment, when the experiment stops.
	 *
	 * @param Nelio_AB_Testing_Experiment $experiment the post object.
	 *
	 * @return void
	 * @since  5.0.0
	 */
	public function log_experiment( $experiment ) {

		$params = array(
			'id'           => $experiment->get_id(),
			'type'         => $experiment->get_type(),
			'name'         => $experiment->get_name(),
			'description'  => $experiment->get_description(),
			'start'        => $experiment->get_start_date(),
			'end'          => $experiment->get_end_date(),
			'endMode'      => $experiment->get_end_mode(),
			'endValue'     => $experiment->get_end_value(),
			'starter'      => $experiment->get_starter(),
			'stopper'      => $experiment->get_stopper(),
			'alternatives' => count( $experiment->get_alternatives() ),
			'goals'        => count( $experiment->get_goals() ),
			'url'          => home_url(),
			'language'     => nab_get_language(),
			'timezone'     => nab_get_timezone(),
			'wpVersion'    => get_bloginfo( 'version' ),
			'nabVersion'   => nelioab()->plugin_version,
		);

		$body = wp_json_encode( $params );
		if ( empty( $body ) ) {
			return; // @codeCoverageIgnore
		}

		$data = array(
			'method'    => 'POST',
			'timeout'   => absint( apply_filters( 'nab_request_timeout', 30 ) ),
			'sslverify' => ! nab_does_api_use_proxy(),
			'headers'   => array(
				'Authorization' => 'Bearer ' . nab_generate_api_auth_token(),
				'accept'        => 'application/json',
				'content-type'  => 'application/json',
			),
			'body'      => $body,
		);

		$url = nab_get_api_url( '/site/' . nab_get_site_id() . '/experiment', 'wp' );
		wp_remote_request( $url, $data );
	}

	/**
	 * Logs the site.
	 *
	 * @return void
	 * @since  5.0.0
	 */
	public function log_site() {

		if ( ! nab_get_site_id() ) {
			return; // @codeCoverageIgnore
		}

		$params = array(
			'url'        => home_url(),
			'language'   => nab_get_language(),
			'timezone'   => nab_get_timezone(),
			'nabVersion' => nelioab()->plugin_version,
			'phpVersion' => preg_replace( '/-.*$/', '', phpversion() ),
			'wpVersion'  => get_bloginfo( 'version' ),
		);

		$body = wp_json_encode( $params );
		if ( empty( $body ) ) {
			return; // @codeCoverageIgnore
		}

		$data = array(
			'method'    => 'PUT',
			'timeout'   => absint( apply_filters( 'nab_request_timeout', 30 ) ),
			'sslverify' => ! nab_does_api_use_proxy(),
			'headers'   => array(
				'Authorization' => 'Bearer ' . nab_generate_api_auth_token(),
				'accept'        => 'application/json',
				'content-type'  => 'application/json',
			),
			'body'      => $body,
		);

		$url = nab_get_api_url( '/site/' . nab_get_site_id(), 'wp' );
		wp_remote_request( $url, $data );
	}

	/**
	 * Callback to maybe log site on upgrade.
	 *
	 * @param WP_Upgrader                       $upgrader WP_Upgrader instance.
	 * @param array{action:string, type:string} $hook_extra Array of bulk item update data.
	 *
	 * @return void
	 */
	public function maybe_log_site_on_upgrade( $upgrader, $hook_extra ) {

		if ( 'update' !== $hook_extra['action'] || 'core' !== $hook_extra['type'] ) {
			return;
		}

		$this->log_site();
	}

	/**
	 * Callback to maybe log site when certain options are updated.
	 *
	 * @param mixed $old_value The old option value.
	 * @param mixed $value     The new option value.
	 *
	 * @return void
	 */
	public function maybe_log_site_on_option_update( $old_value, $value ) {

		if ( $old_value === $value ) {
			return;
		}

		$this->log_site();
	}
}
