<?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 OpenCloud\Common\Error\BadResponseError;
use OpenCloud\Common\Error\BaseError;
use OpenCloud\Common\Error\NotImplementedError;
use OpenCloud\Common\Error\UserInputError;

include("CoreInterface.php");

/**
* 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
	*
	* @return Image
	*/
	public function __construct($app){
		if(!isset($app)){
			$this->app->setOutput("Error", "Incorrect parameter app");
		}
		$this->app = $app;
		$this->libClass = $app->getLibClass("Image");
	}


	/**
	* Execute an action
	*
	* @param String $action name of another function of this class
	*
	* @return void
	*/
	public function action($action){
		 $this->{$action.""}();	
	}

	/**
	* Create a new image
	*
	* @param array $opt Options for the image creation (name is required, others are optionals)
	*
	* @return Image
	*/
	private function createImage(){
		$opt = $this->app->getPostParam("opt");

		if(!isset($opt)){
			$this->app->setOutput("Error", "Incorrect parameter opt");
		}

		try{	
			$options = Array();

			// Check the image name
			if(isset($opt['name'])){ 
				$imagesList = listImage();
				if(isset($imagesList)){
    				foreach($imagesList as $image){
    					if(strcmp($image->name, $opt['name']) == 0){ // if the image name already exists -> error
    						$this->app->setOutput("Error", "Image name already exists");
    					}
    				}
    			}

			}
			else{
				$this->app->setOutput("Error", "Missing parameter 'name' for the new image");
			}

			//  Check optionals arguments
			if(isset($opt['id'])){ // UUID : nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn
				if($this->libClass->getImage($opt['id']) != null){ // if the id already exists -> error
					$this->app->setOutput("Error", "Image id already exists");
				}
				$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);
        }
		$this->app->setOutput("Images", $image);

	}

	/**
	* List the images of the server
	*
	* @return List of Image
	*/
	private function listImage(){
		try{
			$result = array();
			$l = $this->libClass->listImages();
			foreach($l as $tmp){
				$result[] = $tmp;
			}
		}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);
        }

		$this->app->setOutput("Images", $result);

	}

	/**
	* Details about an image
	*
	* @param String $id Identifier of the image
	*	
	* @return Image
	*/
	private function detailsImage(){
		$id = $this->app->getPostParam("id");
		if(!isset($id)){
			$this->app->setOutput("Error", "Incorrect id parameter"); 

		}
		try{
			$service = $this->libClass;
			$image = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist");
			}
			$this->app->setOutput("Images", $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);
        }
	}

	/**
	* Update informations about an image
	*
	* @param String $id id of the image
	* @param array  $opt Options for the image creation
	*	
	* @return Image
	*/

	private function updateImage(){
		$id = $this->app->getPostParam("id");
		$opt = $this->app->getPostParam("opt");

		if(!isset($id)){
			$this->app->setOutput("Error", "Incorrect id parameter"); 
		}
		if(!isset($opt)){
			$this->app->setOutput("Error", "Incorrect opt parameter");
		}

		try{
			//vérifier existence image
			$service = $this->libClass;
			$image = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist");
			}

			$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);
        }
		$this->app->setOutput("Images", $image);
	}

	/**
	* Delete an image
	*
	* @param String $id Identifier of the image
	*	
	* @return void
	*/
	private function deleteImage(){
		// si protected = true, demander de le mettre a false
		// vérifier existence image
		$id = $this->app->getPostParam("id");
		if(!isset($id)){
			$this->app->setOutput("Error", "Image doesn't exist");
		}

		try{
			$service = $this->libClass;
			$image = $this->libClass->getImage($id);
			if($image == null){ // if the image doesn't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist");
			}
			$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
	*	
	* @return void
	*/
	private function reactivateImage(){
		$id = $this->app->getPostParam("id");

		if(!isset($id)){
			$this->app->setOutput("Error", "Incorrect parameter");
		}
		try{
			$service = $this->libClass;
			$image = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist");
			}
			$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
	*
	* @return void	
	*/
	private function desactivateImage(){
		$id = $this->app->getPostParam("id");

		if(!isset($id)){
			$this->app->setOutput("Error", "Incorrect parameter");
		}
		try{
			// vérifier existence image
			$service = $this->libClass;
			$image = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist");
			}
			$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
	*	
	* @return void
	*/
	private function uploadImage(){
		$id = $this->app->getPostParam("id");
		$file_name = $this->app->getPostParam("file_name");


		if(!isset($id)){
			$this->app->setOutput("Error", "Incorrect id parameter");
		}
		if(!isset($file_name)){
			$this->app->setOutput("Error", "Incorrect file name parameter");
		}
		try{
			// vérifier existence image
			$service = $this->libClass;
			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist");
			}
			$stream = \GuzzleHttp\Psr7\stream_for(fopen($file_name, 'r'));
			$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
	*
	* @return Stream
	*/
	private function downloadImage(){
		$id = $this->app->getPostParam("id");

		if(!isset($id)){
			$this->app->setOutput("Error", "Incorrect id parameter");
		}
		try{
			// vérifier existence image 
			$service = $this->libClass;
			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist");
			}
			$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);
        }
        $this->app->setOutput("Images", $stream);
	}

	/**
	* Add a member to image
	*
	* @param String $image_id Identifier of the image
	* @param String $member_id Identifier of the member
	*	
	* @return Member
	*/
	private function addMemberImage(){
		$image_id = $this->app->getPostParam("image_id");
		$member_id = $this->app->getPostParam("member_id");

		if(!isset($image_id)){
			$this->app->setOutput("Error", "Incorrect image id parameter");
		}
		if(!isset($member_id)){
			$this->app->setOutput("Error", "Incorrect member id parameter");
		}
		try{
			$service = $this->libClass;	

			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist");
			}
			$member_id = $image->addMember($member_id);
			$this->app->setOutput("Images", $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
	*
	* @return List of Member 	
	*/
	private function listMemberImage(){
		$image_id = $this->app->getPostParam("image_id");
		$member_id = $this->app->getPostParam("member_id");

		if(!isset($image_id)){
			$this->app->setOutput("Error", "Incorrect image id parameter");
		}
		if(!isset($member_id)){
			$this->app->setOutput("Error", "Incorrect member id parameter"); 
		}
		try{
			// vérifier existence image
			$service = $this->libClass;
			$image = $service->getImage($image_id);
			if($image == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist"); 
			}
			$members = $image->listMembers();
			if($members == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "No member");
			}
		}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);
        }
		$this->app->setOutput("Images", $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
	*
	* @return Member
	*/
	private function detailMemberImage(){
		$image_id = $this->app->getPostParam("image_id");
		$member_id = $this->app->getPostParam("member_id");

		if(!isset($image_id)){
			$this->app->setOutput("Error", "Incorrect image id parameter"); 
		}
		if(!isset($member_id)){
			$this->app->setOutput("Error", "Incorrect member id parameter");
		}
		try{
			$service = $this->libClass;	

			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist");
			}

			$member = $image->getMember($member_id);
			if($member == null){ // if the member don't exists -> error
				$this->app->setOutput("Error", "Member doesn't exist");
			}
		}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);
        }
		$this->app->setOutput("Images", $member);
	}
	
	/**
	* Remove a member of an image
	*
	* @param String $image_id Identifier of the image
	* @param String $member_id Identifier of the member
	*	
	* @return void
	*/
	private function removeMemberImage(){
		$image_id = $this->app->getPostParam("image_id");
		$member_id = $this->app->getPostParam("member_id");

		if(!isset($image_id)){
			$this->app->setOutput("Error", "Incorrect image id parameter"); 
		}
		if(!isset($member_id)){
			$this->app->setOutput("Error", "Incorrect member id parameter");
		}
		try{
			$service = $this->libClass;	

			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist");
			}	
			$member = $image->getMember($member_id);
			if($member == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Member doesn't exist");
			}
			$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
	*
	* @return void	
	**/
	private function updateMemberImage(){
		$image_id = $this->app->getPostParam("image_id");
		$member_id = $this->app->getPostParam("member_id");
		$status = $this->app->getPostParam("status");

		if(!isset($image_id)){
			$this->app->setOutput("Error", "Incorrect image id parameter");
		}
		if(!isset($member_id)){
			$this->app->setOutput("Error", "Incorrect member id parameter");
		}
		try{
			$service = $this->libClass;		

			$image  = $service->getImage($id);
			if($image == null){ // if the image don't exists -> error
				$this->app->setOutput("Error", "Image doesn't exist");
			}
			$member = $image->getMember($member_id);
			if($member == null){ // if the member don't exists -> error
				$this->app->setOutput("Error", "Member doesn't exist");
			}
			$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);
        }
	}

}
?>