<?php
/**
 * Setup Attachments Component
 *
 * @package Nisje
 */

namespace Dekode\Nisje\Components;

defined( 'ABSPATH' ) || die( 'Shame on you' );

/**
 * Attachments Component Class
 */
class Attachments extends Component {
	/**
	 * Constructor
	 */
	public function __construct() {
		parent::start(
			'attachments',
			__( 'Attachments', 'nisje' )
		);
	}

	/**
	 * Include Component files
	 */
	public function includes() {
		nisje_include( 'includes/components/attachments/helper-functions.php' );

		if ( ! version_compare( bp_get_version(), '2.3-alpha', '>=' ) ) {
			return;
		}

		nisje_include( 'includes/components/attachments/includes/class-dekode-bp-attachment.php' );
		nisje_include( 'includes/components/attachments/includes/class-dekode-secure-bp-attachment.php' );
		nisje_include( 'includes/components/attachments/includes/class-dekode-expire-bp-attachment.php' );
	}

	/**
	 * Setup Filters
	 */
	public function setup_filters() {
		add_filter( 'wp_get_attachment_url', [ $this, 'add_expires_to_url' ], 10, 2 );
		add_filter( 'wp_calculate_image_srcset', [ $this, 'add_expires_to_image_srcset' ], 10, 5 );
		add_filter( 'wp_get_attachment_image_src', [ $this, 'add_expires_to_image_src' ], 10, 2 );
	}


	/**
	 * Register REST Endpoints
	 */
	public function register_rest_routes() {
		nisje_include( 'includes/components/attachments/rest-handlers/class-attachments-controller.php' );
		$controller = new \Dekode\Nisje\Components\Rest\Attachments_Controller();

		$controller->register_routes();
	}

	/**
	 * Use the wp_get_attachment_url filter to modify url with hash and expire query args
	 *
	 * @param string $image         Current Image.
	 * @param int    $attachment_id Attachment ID.
	 *
	 * @return string
	 */
	public function add_expires_to_url( $image, $attachment_id ) {
		$timeout = get_post_meta( $attachment_id, 'Dekode_Expire_BP_Attachment', true );

		if ( ! $timeout ) {
			return $image;
		}

		return $this->add_expire_query_args( $image, $timeout, $attachment_id );

	}

	/**
	 * Use the wp_calculate_image_srcset filter to modify url with hash and expire query args
	 *
	 * @param array  $sources       Sources.
	 * @param array  $size_array    Size array.
	 * @param string $image_src     Image source.
	 * @param array  $image_meta    Image meta.
	 * @param int    $attachment_id Attachment ID.
	 *
	 * @return array mixed
	 */
	public function add_expires_to_image_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id ) {
		$timeout = get_post_meta( $attachment_id, 'Dekode_Expire_BP_Attachment', true );

		if ( ! $timeout ) {
			return $sources;
		}

		foreach ( $sources as &$source ) {
			if ( ! isset( $source['url'] ) ) {
				echo 'continue';
				continue;
			}

			$source['url'] = $this->add_expire_query_args( $source['url'], $timeout, $attachment_id );
		}

		return $sources;
	}

	/**
	 * Use the wp_get_attachment_image_src filter to modify url with hash and expire query args
	 *
	 * @param string $url           Attachment URL.
	 * @param int    $attachment_id Attachment ID.
	 *
	 * @return string
	 */
	public function add_expires_to_image_src( $url, $attachment_id ) {

		$timeout = get_post_meta( $attachment_id, 'Dekode_Expire_BP_Attachment', true );

		if ( ! $timeout ) {
			return $url;
		}

		$url[0] = $this->add_expire_query_args( $url[0], $timeout, $attachment_id );

		return $url;

	}

	/**
	 * Generate base64url md5 for use with NGINX Secure Link
	 *
	 * @param int    $expires Expire date.
	 * @param string $path    Path to file.
	 *
	 * @return string
	 */
	private function generate_hash( $expires, $path ) {
		$md5 = md5( "$expires$path nisje", true );
		$md5 = base64_encode( $md5 ); // phpcs:ignore
		$md5 = strtr( $md5, '+/', '-_' );
		$md5 = str_replace( '=', '', $md5 );

		return $md5;
	}

	/**
	 * Add expire timestamp and secure hash to url
	 *
	 * @param string $url           Url that query args will be added to.
	 * @param int    $timeout       UNIX timestamp of when image can no longer be reached.
	 * @param int    $attachment_id ID of the attachment.
	 *
	 * @return string New url with Query args
	 */
	private function add_expire_query_args( $url, $timeout, $attachment_id ) {
		$expires = time() + $timeout;

		$expires = apply_filters( 'dekode_attachment_expires', $expires, $attachment_id );

		$path = strstr( $url, '/content' );

		return add_query_arg( [
			'fe' => $expires,
			'fh' => $this->generate_hash( $expires, $path ),
		], $url );
	}
}
