<?php
/**
 * Jetpack MC Stats package.
 *
 * @package  automattic/jetpack-mc-stats
 */

namespace Automattic\Jetpack;

/**
 * Class MC Stats, used to record stats using https://pixel.wp.com/g.gif
 */
class A8c_Mc_Stats {

	/**
	 * Holds the stats to be processed
	 *
	 * @var array
	 */
	private $stats = array();

	/**
	 * Indicates whether to use the transparent pixel (b.gif) instead of the regular smiley (g.gif)
	 *
	 * @var boolean
	 */
	public $use_transparent_pixel = true;

	/**
	 * Class Constructor
	 *
	 * @param boolean $use_transparent_pixel Use the transparent pixel instead of the smiley.
	 */
	public function __construct( $use_transparent_pixel = true ) {
		$this->use_transparent_pixel = $use_transparent_pixel;
	}

	/**
	 * Store a stat for later output.
	 *
	 * @param string $group The stat group.
	 * @param string $name The stat name to bump.
	 *
	 * @return boolean true if stat successfully added
	 */
	public function add( $group, $name ) {

		if ( ! \is_string( $group ) || ! \is_string( $name ) ) {
			return false;
		}

		if ( ! isset( $this->stats[ $group ] ) ) {
			$this->stats[ $group ] = array();
		}

		if ( \in_array( $name, $this->stats[ $group ], true ) ) {
			return false;
		}

		$this->stats[ $group ][] = $name;

		return true;
	}

	/**
	 * Gets current stats stored to be processed
	 *
	 * @return array $stats
	 */
	public function get_current_stats() {
		return $this->stats;
	}

	/**
	 * Return the stats from a group in an array ready to be added as parameters in a query string
	 *
	 * @param string $group_name The name of the group to retrieve.
	 * @return array Array with one item, where the key is the prefixed group and the value are all stats concatenated with a comma. If group not found, an empty array will be returned
	 */
	public function get_group_query_args( $group_name ) {
		$stats = $this->get_current_stats();
		if ( isset( $stats[ $group_name ] ) && ! empty( $stats[ $group_name ] ) ) {
			return array( "x_jetpack-{$group_name}" => implode( ',', $stats[ $group_name ] ) );
		}
		return array();
	}

	/**
	 * Gets a list of trac URLs for every stored URL
	 *
	 * @return array An array of URLs
	 */
	public function get_stats_urls() {

		$urls = array();

		foreach ( $this->get_current_stats() as $group => $stat ) {
			$group_query_string = $this->get_group_query_args( $group );
			$urls[]             = $this->build_stats_url( $group_query_string );
		}

		return $urls;
	}

	/**
	 * Outputs the tracking pixels for the current stats and empty the stored stats from the object
	 *
	 * @return void
	 */
	public function do_stats() {
		$urls = $this->get_stats_urls();
		foreach ( $urls as $url ) {
			echo '<img src="' . esc_url( $url ) . '" width="1" height="1" style="display:none;" />';
		}
		$this->stats = array();
	}

	/**
	 * Pings the stats server for the current stats and empty the stored stats from the object
	 *
	 * @return void
	 */
	public function do_server_side_stats() {
		$urls = $this->get_stats_urls();
		foreach ( $urls as $url ) {
			$this->do_server_side_stat( $url );
		}
		$this->stats = array();
	}

	/**
	 * Runs stats code for a one-off, server-side.
	 *
	 * @param string $url string The URL to be pinged. Should include `x_jetpack-{$group}={$stats}` or whatever we want to store.
	 *
	 * @return bool If it worked.
	 */
	public function do_server_side_stat( $url ) {
		$response = wp_remote_get( esc_url_raw( $url ) );
		if ( is_wp_error( $response ) ) {
			return false;
		}

		if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
			return false;
		}

		return true;
	}

	/**
	 * Builds the stats url.
	 *
	 * @param array $args array|string The arguments to append to the URL.
	 *
	 * @return string The URL to be pinged.
	 */
	public function build_stats_url( $args ) {
		$defaults = array(
			'v'    => 'wpcom2',
			// phpcs:ignore WordPress.WP.AlternativeFunctions.rand_rand -- There can be a case where pluggables are not yet loaded.
			'rand' => md5( ( function_exists( 'wp_rand' ) ? wp_rand( 0, 999 ) : rand( 0, 999 ) ) . time() ),
		);
		$args     = wp_parse_args( $args, $defaults );
		$gifname  = true === $this->use_transparent_pixel ? 'b.gif' : 'g.gif';

		/**
		 * Filter the URL used as the Stats tracking pixel.
		 *
		 * @since-jetpack 2.3.2
		 * @since 1.0.0
		 *
		 * @param string $url Base URL used as the Stats tracking pixel.
		 */
		$base_url = apply_filters(
			'jetpack_stats_base_url',
			'https://pixel.wp.com/' . $gifname
		);
		$url      = add_query_arg( $args, $base_url );
		return $url;
	}
}
