<?php

namespace Smush\Core\Smush;

use Smush\Core\Array_Utils;
use Smush\Core\File_System;
use Smush\Core\File_Utils;

/**
 * Calls the API and returns the response.
 */
abstract class Smush_Request {
	/**
	 * @var int
	 */
	private $timeout;
	/**
	 * @var int
	 */
	private $connect_timeout = 5;
	/**
	 * @var string
	 */
	private $user_agent;
	/**
	 * @var
	 */
	private $on_complete = '__return_false';
	/**
	 * @var Array_Utils
	 */
	private $array_utils;
	/**
	 * @var File_Utils
	 */
	private $file_utils;
	/**
	 * @var bool
	 */
	private $streaming_enabled;
	/**
	 * @var File_System
	 */
	private $fs;
	/**
	 * @var array
	 */
	private $extra_headers;
	/**
	 * @var Smusher_Options
	 */
	private $options;

	public function __construct( $options ) {
		$this->options           = $options;
		$this->streaming_enabled = $options->is_streaming_enabled();
		$this->extra_headers     = $options->get_extra_headers();
		$this->array_utils       = new Array_Utils();
		$this->file_utils        = new File_Utils();
		$this->fs                = new File_System();
		$this->user_agent        = WP_SMUSH_UA;
		$this->timeout           = WP_SMUSH_TIMEOUT;
	}

	public function get_on_complete() {
		return $this->on_complete;
	}

	public function set_on_complete( $on_complete ) {
		$this->on_complete = $on_complete;

		return $this;
	}

	public function get_connect_timeout() {
		return $this->connect_timeout;
	}

	public function get_timeout() {
		return $this->timeout;
	}

	public function get_user_agent() {
		return $this->user_agent;
	}

	public function get_url() {
		return $this->options->get_api_url();
	}

	/**
	 * @return string[]
	 */
	public function get_api_request_headers( $file_path ) {
		$headers = array_merge(
			array(
				'accept' => 'application/json', // The API returns JSON.
				'exif'   => $this->options->strip_exif() ? 'false' : 'true',
			),
			$this->get_extra_headers()
		);

		if ( $this->streaming_enabled ) {
			$headers['response'] = 'image_url';
		} else {
			$headers['response'] = 'image_full';
		}

		$headers['content-type'] = 'application/binary';

		$headers['lossy'] = $this->options->get_lossy_level();

		// Check if premium member, add API key.
		$api_key = $this->options->get_api_key();
		if ( ! empty( $api_key ) ) {
			$headers['apikey'] = $api_key;

			$is_large_file = $this->file_utils->is_large_file( $file_path );
			if ( $is_large_file ) {
				$headers['islarge'] = 1;
			}
		}

		return $headers;
	}

	public function get_full_file_contents( $file_path ) {
		// Temporary increase the limit because we are about to read a full file into memory.
		wp_raise_memory_limit( 'image' );

		$contents = $this->fs->file_get_contents( $file_path );
		return empty( $contents ) ? '' : $contents;
	}

	/**
	 * @param $file_data string|array
	 *
	 * @return array
	 */
	protected function get_file_path_and_url( $file_data ) {
		if ( is_string( $file_data ) ) {
			$file_path = $file_data;
			$file_url  = '';
		} else {
			$file_path = $this->array_utils->get_array_value( $file_data, 'path' );
			$file_url  = $this->array_utils->get_array_value( $file_data, 'url' );
		}
		return array( $file_path, $file_url );
	}

	public function get_extra_headers() {
		return $this->extra_headers;
	}

	public function set_extra_headers( $extra_headers ) {
		$this->extra_headers = $extra_headers;
		return $this;
	}

	public function do_request( $file_path, $size_key ) {
		return false;
	}

	public function set_streaming_enabled( $streaming_enabled ) {
		$this->streaming_enabled = $streaming_enabled;
		return $this;
	}

	public function is_streaming_enabled() {
		return $this->streaming_enabled;
	}

	/**
	 * @param $file_paths array
	 *
	 * @return mixed
	 */
	abstract public function do_requests( $file_paths );

	abstract public function is_supported();
}
