<?php
/**
* File containing the Image Class.
*
* @version 1.0 Initialisation of this file
* @since 1.0 Core application's file
* 
* @author Yogg 'yogg at epsina . com'
* 
* @todo Complete the functions with errors detection and finish the descriptions
*/
use OpenStack\Common\Error\BadResponseError;
use OpenStack\Common\Error\BaseError;
use OpenStack\Common\Error\NotImplementedError;
use OpenStack\Common\Error\UserInputError;

/**
* Image Class of the back-end application
*
* ADD CLASS DESCRIPTION
*
*/
class image { 
	//implements Core

	/** @var App $app protected, contains the main app object */
	protected $app;
	
	/** @var OpenStack\Identity $libClass protected, contains the library Identity object */
	protected $libClass;
	
	/**
	* Image constructor
	*
	* @param App $app the main app object
	*
	* @throws [Type] [<description>]
	*
	* @return Image
	*/
	public function __construct($app){
		if(!isset($app)){
			// Renvoyer erreur 
		}
		try{
			$this->app = $app;
			$this->libClass = $app->getLibClass("Image");
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
	}


	private $images = array();

	/**
	* Details about an image
	*
	* @param array $opt
	*	options for the image creation
	*
	**/
	public function createImage(array $opt){

		if(!isset($opt)){
			// Renvoyer erreur 
		}


		try{	
			// VOIR SI MAUVAIS TYPE
			$options = Array();
			if(isset($opt['name'])){ // if the image name already exists -> error
				$imagesList = listImage();
				if(isset($images)){
    				foreach($imagesList as $image){
    					if(strcmp($image->name, $opt['name']) == 0){

    					}
    				}
    			}

			}
			else{
				//ERROR
			}
			if(isset($opt['id'])){ // UUID : nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn
				if($this->libClass->getImage($opt['id']) != null){ // if the id already exists -> error

				}
				$options['id'] = $opt['id'];
			}
			if(isset($opt['visibility'])){ // public, private
				$options['visibility'] = $opt['visibility'];
			}
			if(isset($opt['tags'])){ // list
				$options['tags'] = $opt['tags'];
			}
			if(isset($opt['containerFormat'])){ // string : ami, ari, aki, bare, ovf, ova, docker
				$options['containerFormat'] = $opt['containerFormat'];
			}
			if(isset($opt['diskFormat'])){ // string : ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, iso
				$options['diskFormat'] = $opt['diskFormat'];
			}
			if(isset($opt['minDisk'])){ //int
				$options['minDisk'] = $opt['minDisk'];
			}
			if(isset($opt['minRam'])){ // int
				$options['minRam'] = $opt['minRam'];
			}
			if(isset($opt['protected'])){ // boolean
				$options['protected'] = $opt['protected'];
			}
			if(isset($opt['properties'])){ // type dict ?
				$options['properties'] = $opt['properties'];
			}	

			$image = $this->libClass->createImage($options);
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
		return $image;
	}

	/**
	* List the images of the server
	*
	* @return the list with all images on the server
	*/
	public function listImage(){
		try{
			$l = $this->libClass->listImages();
			if(!isset($l)){ // if the list is empty there is no images

			}
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
		return $l;

	}

	/**
	* Details about an image
	*
	* @param string $id
	*	identifier of the image
	*
	**/
	public function detailsImage($id){
		if(!isset($id)){
			// Renvoyer erreur 
		}
		try{
			$service = $this->libClass;
			$image = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
			
			return $image;
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
	}

	/**
	* Details about an image
	*
	* @param string $id
	*	id of the image
	*
	* @param array $opt
	*	options for the image creation
	**/
	public function updateImage($id, array $opt){
		if(!isset($id)){
			// Renvoyer erreur 
		}
		if(!isset($opt)){
			// Renvoyer erreur 
		}

		try{
			//vérifier existence image
			$service = $this->libClass;
			$image = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
			// Renvoyer erreur 
			}

			$options = Array();

			// Voir vérification des types
			if(isset($opt['name'])){ //string
				$options['name'] = $opt['name'];
			}
			if(isset($opt['minDisk'])){ //int
				$options['minDisk'] = $opt['minDisk'];
			}
			if(isset($opt['minRam'])){ // int
				$options['minRam'] = $opt['minRam'];
			}
			if(isset($opt['protected'])){ // boolean
				$options['protected'] = $opt['protected'];
			}
			if(isset($opt['visibility'])){ // public, private
				$options['visibility'] = $opt['visibility'];
			}
			if(isset($opt['tags'])){ // list
				$options['tags'] = $opt['tags'];
			}
			$image->update($options);
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
		return $image;
	}

	/**
	* Delete an image
	*
	* @param string $id
	*	identifier of the image
	**/
	public function deleteImage($id){
		// si protected = true, demander de le mettre a false
		// vérifier existence image
		if(!isset($id)){
			// Renvoyer erreur 
		}

		try{
			$service = $this->libClass;
			$image = $this->libClass->getImage($id);
			if($image == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
			$image->delete();
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
		
	}

	/**
	* Resactive an image
	*
	* @param string $id
	*	identifier of the image
	**/
	public function reactivateImage($id){
		if(!isset($id)){
			// Renvoyer erreur 
		}
		try{
			// vérifier existence image
			$service = $this->libClass;
			$image = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
			$image->reactivate();
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
	}

	/**
	* Desactive an image
	*
	* @param string $id
	*	identifier of the image
	**/
	public function desactivateImage($id){
		if(!isset($id)){
			// Renvoyer erreur 
		}
		try{
			// vérifier existence image
			$service = $this->libClass;
			$image = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
			$image->deactivate();
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
	}

	/**
	* Upload an image
	*
	* @param string $id
	*	identifier of the image
	* 
	* @param string $file_name
	*	path of the image
	**/
	public function uploadImage($id, $file_name){
		if(!isset($id)){
			// Renvoyer erreur 
		}
		if(!isset($file_name)){
			// Renvoyer erreur 
		}
		try{
			// vérifier existence image
			$service = $this->libClass;
			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
			$stream = \GuzzleHttp\Psr7\stream_for(fopen($file_name, 'r')); // A VOIR
			$image->uploadData($stream);
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
	}

	/**
	* Download an image
	*
	* @param string $id
	*	identifier of the image
	**/
	public function downloadImage($id){
		if(!isset($id)){
			// Renvoyer erreur 
		}
		try{
			// vérifier existence image 
			$service = $this->libClass;
			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
			$stream = $image->downloadData();
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
        return $stream;
	}

	/**
	* Add a member to image
	*
	* @param string $image_id
	*	identifier of the image
	*
	* @param string $member_id
	*	identifier of the member
	**/
	public function addMemberImage($image_id, $member_id){
		if(!isset($image_id)){
			// Renvoyer erreur 
		}
		if(!isset($member_id)){
			// Renvoyer erreur 
		}
		try{
			// vérifier existence image
			// on doit être le proprio de l'image
			// vérifier membre existe
			$service = $this->libClass;	

			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}

			$member_id = $image->addMember($member_id);
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
	}

	
	/**
	* List members of an image
	*
	* @param string $image_id
	*	identifier of the image
	**/
	public function listMemberImage($image_id, $member_id){
		if(!isset($image_id)){
			// Renvoyer erreur 
		}
		if(!isset($member_id)){
			// Renvoyer erreur 
		}
		try{
			// vérifier existence image
			$service = $this->libClass;
			$image = $service->getImage($image_id);
			if($image == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
			$members = $image->listMembers();
			if($member == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
		return $members;
	}

	/**
	* Show details of a member of an image
	*
	* @param string $image_id
	*	identifier of the image
	*
	* @param string $member_id
	*	identifier of the member
	**/
	public function detailMemberImage($image_id, $member_id){
		if(!isset($image_id)){
			// Renvoyer erreur 
		}
		if(!isset($member_id)){
			// Renvoyer erreur 
		}
		try{
			// vérifier existence image
			// on doit être le proprio de l'image
			// vérifier membre existe
			$service = $this->libClass;	

			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}

			$member = $image->getMember($member_id);
			if($member == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
		return $member;
	}
	
	/**
	* Remove a member of an image
	*
	* @param string $image_id
	*	identifier of the image
	*
	* @param string $member_id
	*	identifier of the member
	**/
	public function removeMemberImage($image_id, $member_id){
		if(!isset($image_id)){
			// Renvoyer erreur 
		}
		if(!isset($member_id)){
			// Renvoyer erreur 
		}
		try{
			// vérifier existence image
			// on doit être le proprio de l'image
			// vérifier membre existe
			$service = $this->libClass;	

			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}	
			$member = $image->getMember($member_id);
			if($member == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
			$member->delete();
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
	}

	/**
	* Update a member of an image
	*
	* @param string $image_id
	*	identifier of the image
	*
	* @param string $member_id
	*	identifier of the member
	*
	* @param string $status
	*	new status for the member
	**/
	public function updateMemberImage($image_id, $member_id, $status){
		if(!isset($image_id)){
			// Renvoyer erreur 
		}
		if(!isset($member_id)){
			// Renvoyer erreur 
		}
		try{
			// vérifier existence image
			// on doit être le proprio de l'image
			// vérifier membre existe
			$service = $this->libClass;		

			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
			$member = $image->getMember($member_id);
			if($member == null){ // if the image don't exists -> error
				// Renvoyer erreur 
			}
			$member->updateStatus($status);
		}catch(BadResponseError $e){
			$this->app->getErrorInstance()->BadResponseHandler($e);
        }catch(UserInputError $e){
			$this->app->getErrorInstance->UserInputHandler($e);
        }catch(BaseError $e){
			$this->app->getErrorInstance->BaseErrorHandler($e);
        }catch(NotImplementedError $e){
			$this->app->getErrorInstance->NotImplementedHandler($e);
        }
	}

}
?>