<?php
/**
 * Amazon S3 Bucket class.
 *
 * @link  http://www.boldgrid.com
 * @since 1.0.0
 *
 * @package    Boldgrid_Backup
 * @subpackage Boldgrid_Backup/admin
 * @copyright  BoldGrid.com
 * @version    $Id$
 * @author     BoldGrid.com <wpb@boldgrid.com>
 */

/**
 * Amazon S3 Bucket class.
 *
 * @since 1.0.0
 */
class Boldgrid_Backup_Premium_Admin_Remote_Amazon_S3_Bucket {

	/**
	 * The core class object.
	 *
	 * @since 1.0.0
	 * @var Boldgrid_Backup_Admin_Core
	 */
	private $core;

	/**
	 * Errors.
	 *
	 * @since 1.0.0
	 * @var   array
	 */
	public $errors = array();

	/**
	 * An instance of Boldgrid_Backup_Premium_Admin_Core.
	 *
	 * @since 1.0.0
	 * @var   Boldgrid_Backup_Premium_Admin_Core
	 */
	private $premium_core;

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 *
	 * @param Boldgrid_Backup_Admin_Core $core Core class object.
	 */
	public function __construct( $core, $premium_core ) {
		$this->core = $core;
		$this->premium_core = $premium_core;
	}

	/**
	 * Delete bucket transients.
	 *
	 * @since 1.5.4
	 */
	public function delete_transients() {
		$bucket_id = $this->premium_core->amazon_s3->bucket_id;

		$transient = sprintf( 'boldgrid_backup_s3_bucket_w_headers_%1$s', $bucket_id );
		delete_transient( $transient );

		$transient = sprintf( 'boldgrid_backup_s3_bucket_%1$s', $bucket_id );
		delete_transient( $transient );
	}

	/**
	 * Get the contents of a bucket.
	 *
	 * @since 1.0.0
	 *
	 * @param  string $bucket_id
	 * @param  bool   $include_headers
	 * @return array  https://pastebin.com/uVkx8t5A
	 */
	public function get( $bucket_id = null, $include_headers = false ) {

		// Shorten for readability.
		$s3 = $this->premium_core->amazon_s3;

		$s3->set_client();
		if( empty( $s3->client ) ) {
			return array();
		}

		if( ! empty( $bucket_id ) ) {
			$s3->set_bucket_id( $bucket_id );
		}

		$transient_name = sprintf(
			'boldgrid_backup_s3_bucket_%1$s%2$s',
			$include_headers ? 'w_headers_' : '',
			$s3->bucket_id
		);

		$bucket_contents = get_transient( $transient_name );
		if( false !== $bucket_contents ) {
			return $bucket_contents;
		}

		$bucket_contents = array();

		// If the bucket does not exist, return an empty bucket.
		try{
			$iterator = $s3->client->getIterator( 'ListObjects', array(
				'Bucket' => $s3->bucket_id
			));

			foreach( $iterator as $object ) {
				if( $include_headers ) {
					$object['Headers'] = $s3->get_headers( $object['Key'] );
				}

				$bucket_contents[] = $object;
			}
		} catch( Aws\S3\Exception\NoSuchBucketException $e ) {
			return array();
		}

		set_transient( $transient_name, $bucket_contents, 5 * MINUTE_IN_SECONDS );

		return $bucket_contents;
	}

	/**
	 * Get an item from the bucket.
	 *
	 * @since 1.5.4
	 *
	 * @param  string $key
	 * @return mixed Array on success, false on failure.
	 */
	public function get_item( $key ) {
		$bucket_contents = $this->get();

		foreach( $bucket_contents as $item ) {
			if( $item['Key'] === $key ) {
				return $item;
			}
		}

		return false;
	}

	/**
	 * Validate a local backup matches the remove backup.
	 *
	 * @since 1.5.4
	 *
	 * @param string $key
	 */
	public function validate_backup( $key ) {
		$item = $this->get_item( $key );

		$local_path = $this->core->backup_dir->get_path_to( $key );
		$local = $this->core->wp_filesystem->dirlist( $local_path );

		$remote_size = ! empty( $item['Size'] ) ? intval( $item['Size'] ) : null;
		$local_size = ! empty( $local[$key]['size'] ) ? intval( $local[$key]['size'] ) : null;

		if( empty( $remote_size ) || empty( $local_size ) ) {
			return false;
		}

		$same_size = $remote_size === $local_size;
		if( ! $same_size ) {
			$this->errors[] = sprintf(
				__( 'Downloaded filesize (%1$s) does not match remote filesize (%2$s).', 'boldgrid-backup' ),
				$local_size,
				$remote_size
			);
		}

		return $same_size;
	}
}
