<?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;

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
	*
	* @throws [Type] [<description>]
	*
	* @return Image
	*/
	public function __construct($app){
		if(!isset($app)){
			$this->app->setOutput("Error", "Incorrect parameter");
		}
		$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.""}();
		
	}

	/**
	* Details about an image
	*
	* @param array $opt
	*	options for the image creation
	*
	**/
	private function createImage(array $opt){
		$opt = $this->app->getPostParam("opt");

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


		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{
				$this->app->setOutput("Error", "Image name already exists");
			}
			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);
        }
		$this->app->setOutput("Images", $image);
	}

	/**
	* List the images of the server
	*
	* @return the list with all images on the server
	*/
	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
	*
	**/
	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);
        }
	}

	/**
	* Details about an image
	*
	* @param string $id
	*	id of the image
	*
	* @param array $opt
	*	options for the image creation
	**/
	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
	**/
	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 don'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
	**/
	private function reactivateImage(){
		$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->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
	**/
	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
	**/
	private function uploadImage($id, $file_name){
		$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
	**/
	private function downloadImage($id){
		$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");
			}
			$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
	**/
	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 parameter image_id");
		}
		if(!isset($member_id)){
			$this->app->setOutput("Error", "Incorrect parameter member_id");
		}
		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);
		}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
	**/
	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 parameter image_id");
		}
		if(!isset($member_id)){
			$this->app->setOutput("Error", "Incorrect parameter member_id"); 
		}
		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($member == 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", $member);
	}

	/**
	* Show details of a member of an image
	*
	* @param string $image_id
	*	identifier of the image
	*
	* @param string $member_id
	*	identifier of the 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 parameter image_id"); 
		}
		if(!isset($member_id)){
			$this->app->setOutput("Error", "Incorrect parameter member_id");
		}
		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
				$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
	**/
	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 parameter image_id"); 
		}
		if(!isset($member_id)){
			$this->app->setOutput("Error", "Incorrect parameter member_id");
		}
		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
	**/
	private function updateMemberImage($image_id, $member_id, $status){
		$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 parameter image_id");
		}
		if(!isset($member_id)){
			$this->app->setOutput("Error", "Incorrect parameter member_id");
		}
		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);
        }
	}

}
?>