<?php


	/** DOCKERENVIRONMENT / DOCKERENVIRONMENT **/
	//Récuperation d'une liste de DockerEnvironment
	Action::register('docker_environment_search',function(&$response){
		global $_;
		User::check_access('docker','read');
		Plugin::need('client/Client');
		require_once(__DIR__.SLASH.'DockerEnvironment.class.php');
		require_once(__DIR__.SLASH.'DockerMachine.class.php');
		
		// OPTIONS DE RECHERCHE, A ACTIVER POUR UNE RECHERCHE AVANCEE
		$query = 'SELECT {{table}}.*,'.Client::joinString('c').' FROM '.DockerEnvironment::tableName().' LEFT JOIN '.Client::tableName().' c ON {{table}}.client = c.id WHERE 1';
		$data = array();
		//Recherche simple
		if(!empty($_['filters']['keyword'])){
			$query .= ' AND label LIKE ?';
			$data[] = '%'.$_['filters']['keyword'].'%';
		}

		//Recherche avancée
		if(isset($_['filters']['advanced'])) filter_secure_query($_['filters']['advanced'],array('machine','client','domain','port','git','memory','cpu','ssl','state'),$query,$data);

		//Tri des colonnes
		if(isset($_['sort'])) sort_secure_query($_['sort'],array('machine','client','domain','port','mysqlRootPassword','mysqlPassword','git','memory','cpu','ssl','state','certificate'),$query,$data);

		//Pagination
		$response['pagination'] = DockerEnvironment::paginate(20,(!empty($_['page'])?$_['page']:0),$query,$data);

		$DockerEnvironments = DockerEnvironment::staticQuery($query,$data,true,1);
		
		foreach($DockerEnvironments as $dockerEnvironment){
			$row = $dockerEnvironment->toArray();
			$row['state'] = DockerEnvironment::states($row['state']); 
			$row['client'] = $dockerEnvironment->join('client')->toArray(); 
			$response['rows'][] = $row;
		}
		
		/* Mode export */
		if($_['export'] == 'true'){
			$stream = Excel::exportArray($response['rows'],null,'Export');
			File::downloadStream($stream,'export-demandes-'.date('d-m-Y').'.xlsx');
			exit();
		}
		
	});

	//Affichage d'un tab
	Action::register('docker_environment_tab',function(&$response){
		User::check_access('docker','read');
		global $myUser,$_;
		global $conf;
		User::check_access('docker','read');
		require_once(__DIR__.SLASH.'DockerEnvironment.class.php');
		require_once(__DIR__.SLASH.'DockerMachine.class.php');


		$environment = DockerEnvironment::provide();
		$machine = new DockerMachine();
		if($environment->id == 0){
			$environment->memory = '256';
			$environment->cpu = '0.5';
			$environment->port = DockerEnvironment::lastPort()+2;
		}else{
			$machine = DockerMachine::getById($environment->machine);
		}

		$_['tab'] = str_replace('.', '', $_['tab']);
		$tab = __DIR__.SLASH.'tab.environment.'.$_['tab'].'.php';
		if(!file_exists($tab)) throw new Exception("$tab n'existe pas");
		require_once($tab);
		exit();
	});
	
	//Ajout ou modification d'élément DockerEnvironment
	Action::register('docker_environment_save',function(&$response){
	
		global $myUser,$_;
			User::check_access('docker','edit');
			require_once(__DIR__.SLASH.'DockerEnvironment.class.php');
			$item = DockerEnvironment::provide();

			//if(empty($_['domain'])) throw new Exception("Domaine obligatoire");
			if(empty($_['machine'])) throw new Exception("Machine obligatoire");
			//if(empty($_['memory'])) throw new Exception("Mémoire obligatoire");
			//if(!is_numeric($_['memory'])) throw new Exception("La mémoire doit être numérique");
		
			$item->client = $_['client'];
			if($item->id==0) $item->state = DockerEnvironment::ACTIVE;
			$item->machine = $_['machine'];
			if(!empty($_['memory']))  $item->memory = $_['memory'];
			if(!empty($_['ssl'])){
				$item->ssl = $_['ssl'];
			    $item->certificate = $_['certificate'];
			}
			$item->comment = $_['comment'];
			

			//déduction automatique du port interne, on laisse un interval de deux (port web + port phpmyadmin)
			if($item->id==0){

				$item->port = DockerEnvironment::lastPort()+2;

				//génération des mots de passes mysql
				$item->mysqlPassword = sha1('mysql'.mt_rand(0,10000).'hash');
				$item->mysqlRootPassword = sha1('root'.time().$item->mysqlPassword.'hash');
				if(strlen($item->mysqlPassword)>10) $item->mysqlPassword = substr($item->mysqlPassword, 0,9);
				if(strlen($item->mysqlRootPassword)>10) $item->mysqlRootPassword = substr($item->mysqlRootPassword, 0,9);
			}else{
				if(!empty($_['port'])) $item->port = $_['port'];
				if(!empty($_['mysqlRootPassword'])) $item->mysqlRootPassword = $_['mysqlRootPassword'];
				if(!empty($_['mysqlPassword'])) $item->mysqlPassword = $_['mysqlPassword'];
			}

			$item->mysqlRootPassword = encrypt($item->mysqlRootPassword);
			$item->mysqlPassword = encrypt($item->mysqlPassword);

			if(!empty($_['domain'])){
				$item->domain = $_['domain'];
				//suppression du http ou https si existant
				$item->domain = trim(mb_strtolower(preg_replace('/http[s]?:\/\//iU', '', $item->domain)));
				///suppression du www. si existant
				$item->domain = preg_replace('/www\./iU', '', $item->domain);
			}
			$item->save();
			$response =  $item->toArray();

	});
	
	

	//Suppression d'élement DockerEnvironment
	Action::register('docker_environment_delete',function(&$response){
		global $_;
		User::check_access('docker','delete');
		require_once(__DIR__.SLASH.'DockerEnvironment.class.php');
		if(empty($_['id']) || !is_numeric($_['id'])) throw new Exception("Identifiant incorrect");
		DockerEnvironment::deleteById($_['id']);
	});


	//Recherche des certificats installés sur l'utm
	Action::register('docker_environment_certificate_search',function(&$response){
			global $myUser,$_,$conf;

			User::check_access('docker','read');

			require_once(__DIR__.SLASH.'SophosUtm.class.php');
			$utm = new SophosUtm();
			$utm->host = $conf->get('docker_sophos_host');
			$utm->port = $conf->get('docker_sophos_port');
			$utm->login = $conf->get('docker_sophos_login');
			$utm->password = $conf->get('docker_sophos_password');

			foreach ($utm->getCertificates() as $line) {
				$response['rows'][] = array(
					'ref' => $line['_ref'],
					'label' => $line['name']
				);
			};
	});
	
		
	//Ajout ou modification d'élément DockerEnvironment
	Action::register('docker_environment_docker_create',function(&$response){
			global $myUser,$_,$conf;
			User::check_access('docker','edit');
			require_once(__DIR__.SLASH.'DockerEnvironment.class.php');
			require_once(__DIR__.SLASH.'DockerMachine.class.php');
			require_once(__DIR__.SLASH.'SshClient.class.php');
			if(empty($_['id'])) throw new Exception("Environnement obligatoire");
			$environment = DockerEnvironment::provide();
			if(!$environment) throw new Exception("Environnement introuvable");
			
			if(empty($environment->domain)) throw new Exception("Veuillez spécifier un nom de domaine dans l'onglet domaine et enregistrer avant de génerer un environnement");
			

			$ssh = new SshClient();
			$logs = array();
		
			$machine = DockerMachine::getById($environment->machine);
			$logs[]= $ssh->connect(
				$machine->ip,
				$machine->port,
				File::dir().'docker'.SLASH.'machine'.SLASH.$machine->id.SLASH.'id_rsa.pub',
				File::dir().'docker'.SLASH.'machine'.SLASH.$machine->id.SLASH.'id_rsa',
				!empty($machine->password)? decrypt($machine->password) : ''
			);

			$logs[]= $environment->createContainer($ssh);
			$logs[]= $environment->execute($ssh);
			
			$ssh->disconnect();
			$response['logs'] = implode('<br>',$logs);
	});
	
	//Suppression de l'environnement docker
	Action::register('docker_environment_docker_remove',function(&$response){
			global $myUser,$_,$conf;
			User::check_access('docker','edit');
			require_once(__DIR__.SLASH.'DockerEnvironment.class.php');
			require_once(__DIR__.SLASH.'DockerMachine.class.php');
			require_once(__DIR__.SLASH.'SshClient.class.php');
			if(empty($_['id'])) throw new Exception("Environnement obligatoire");
			$environment = DockerEnvironment::provide();
			if(!$environment) throw new Exception("Environnement introuvable");
			
			$ssh = new SshClient();
			$logs = array();
		
			$machine = DockerMachine::getById($environment->machine);
			$logs[]= $ssh->connect(
				$machine->ip,
				$machine->port,
				File::dir().'docker'.SLASH.'machine'.SLASH.$machine->id.SLASH.'id_rsa.pub',
				File::dir().'docker'.SLASH.'machine'.SLASH.$machine->id.SLASH.'id_rsa',
				!empty($machine->password)? decrypt($machine->password) : ''
			);

			$logs[]= $environment->removeContainer($ssh);
		
			
			$ssh->disconnect();
			$response['logs'] = implode('<br>',$logs);
	});

	//Ajout ou modification d'élément DockerEnvironment
	Action::register('docker_environment_pma_create',function(&$response){
			global $myUser,$_,$conf;
			User::check_access('docker','edit');
			require_once(__DIR__.SLASH.'DockerEnvironment.class.php');
			require_once(__DIR__.SLASH.'DockerMachine.class.php');
			require_once(__DIR__.SLASH.'SshClient.class.php');
			if(empty($_['id'])) throw new Exception("Environnement obligatoire");
			$environment = DockerEnvironment::provide();
			if(!$environment) throw new Exception("Environnement introuvable");
			
			$ssh = new SshClient();
			$logs = array();
		
			$machine = DockerMachine::getById($environment->machine);
			$logs[]= $ssh->connect(
				$machine->ip,
				$machine->port,
				File::dir().'docker'.SLASH.'machine'.SLASH.$machine->id.SLASH.'id_rsa.pub',
				File::dir().'docker'.SLASH.'machine'.SLASH.$machine->id.SLASH.'id_rsa',
				!empty($machine->password)? decrypt($machine->password) : ''
			);

			$logs[]= $environment->createPma($ssh);
			
			$ssh->disconnect();
			$response['logs'] = implode('<br>',$logs);
	});
	
	//Ajout ou modification d'élément DockerEnvironment
	Action::register('docker_environment_pma_remove',function(&$response){
			global $myUser,$_,$conf;
			User::check_access('docker','edit');
			require_once(__DIR__.SLASH.'DockerEnvironment.class.php');
			require_once(__DIR__.SLASH.'DockerMachine.class.php');
			require_once(__DIR__.SLASH.'SshClient.class.php');
			if(empty($_['id'])) throw new Exception("Environnement obligatoire");
			$environment = DockerEnvironment::provide();
			if(!$environment) throw new Exception("Environnement introuvable");
			
			$ssh = new SshClient();
			$logs = array();
		
			$machine = DockerMachine::getById($environment->machine);
			$logs[]= $ssh->connect(
				$machine->ip,
				$machine->port,
				File::dir().'docker'.SLASH.'machine'.SLASH.$machine->id.SLASH.'id_rsa.pub',
				File::dir().'docker'.SLASH.'machine'.SLASH.$machine->id.SLASH.'id_rsa',
				!empty($machine->password)? decrypt($machine->password) : ''
			);

			$logs[]= $environment->removePma($ssh);
		
			
			$ssh->disconnect();
			$response['logs'] = implode('<br>',$logs);
	});

	//Ajout ou modification d'élément DockerEnvironment
	Action::register('docker_environment_utm_create',function(&$response){
			global $myUser,$_,$conf;
			User::check_access('docker','edit');
			require_once(__DIR__.SLASH.'DockerEnvironment.class.php');
			require_once(__DIR__.SLASH.'DockerMachine.class.php');
			require_once(__DIR__.SLASH.'SophosUtm.class.php');
			Plugin::need('client/Client');
			if(empty($_['id'])) throw new Exception("Environnement obligatoire");
			$environment = DockerEnvironment::provide('id',1);
			if(!$environment) throw new Exception("Environnement introuvable");
			
			$machine = $environment->join('machine');

			$utm = new SophosUtm();
			$utm->host = $conf->get('docker_sophos_host');
			$utm->port = $conf->get('docker_sophos_port');
			$utm->login = $conf->get('docker_sophos_login');
			$utm->password = $conf->get('docker_sophos_password');
			
			$hostReference = $machine->sophosReference; // ex : REF_RevFroDockeWordpMulti 
			
			if(empty($hostReference)) throw new Exception("Référence du vhost ciblé non renseignée, merci de templir  dans réglages ce parametre", 1);
			
			$domains = array($environment->domain,'www.'.$environment->domain);
			
			$response = $utm->createVHost($environment->domain.' ('.($environment->ssl?'443':'80').') ',$domains,$environment->ssl?443:80,$hostReference, $environment->certificate);
				

			$logs = array('<pre>'.json_encode($response,JSON_PRETTY_PRINT).'</pre>' );
			
			$history = new History();
			$history->scope = 'docker';
			$history->uid = $environment->id;
			$history->comment = 'Création du host utm : '.$environment->domain;
			$history->type = 'utm-save'; 
			$history->save();
			
			$response['logs'] = implode('<br>',$logs);
	});


	Action::register('docker_ovh_consumerKey_generate',function(&$response){
		
			global $myUser,$_,$conf;
			User::check_access('docker','edit');
			require_once(__DIR__.SLASH.'Ovh.class.php');
			$ovh = new Ovh();
			$ovh->host =  $conf->get('docker_ovh_host');
			$ovh->applicationKey = $conf->get('docker_ovh_application_key');
			$ovh->applicationSecret = $conf->get('docker_ovh_application_secret');
			$consumerKey= $ovh->consumerKey();
			//pour genrer cette clé, executer la méthode $ovh->consumerKey() puis aller manuellement sur l'url retournée et valider en mode illimité
			$conf->put('docker_ovh_consumer_key',$consumerKey['consumerKey']);
			header('location: '.$consumerKey['validationUrl']);

	});

	Action::register('docker_environment_domain_create',function(&$response){

			global $myUser,$_,$conf;
			User::check_access('docker','edit');
			require_once(__DIR__.SLASH.'DockerEnvironment.class.php');
			require_once(__DIR__.SLASH.'DockerMachine.class.php');
			require_once(__DIR__.SLASH.'Ovh.class.php');
			Plugin::need('client/Client');
			if(empty($_['id'])) throw new Exception("Environnement obligatoire");
			$environment = DockerEnvironment::provide('id',1);
			if(!$environment) throw new Exception("Environnement introuvable");
			$machine = $environment->join('machine');

			
			$ovh = new Ovh();
			$ovh->host =  $conf->get('docker_ovh_host');
			//generée grace à https://eu.api.ovh.com/createApp/
			$ovh->applicationKey = $conf->get('docker_ovh_application_key');
			$ovh->applicationSecret = $conf->get('docker_ovh_application_secret');
			//pour genrer cette clé, executer la méthode $ovh->consumerKey() puis aller manuellement sur l'url retournée et valider en mode illimité
			$ovh->consumerKey= $conf->get('docker_ovh_consumer_key');

			$subdomain = '';
			$domain = $environment->domain;

			$infos = explode('.',$domain);
			if(count($infos)>2){
				$subdomain = array_shift($infos);
				$domain = implode('.',$infos);
			}

			
			$existingDomains = $ovh->getDomain($domain);
			if(isset($existingDomains['message'])) throw new Exception("Erreur de creation : ".$existingDomains['message']);
			
		
			//ex pour test.kiss.biz CNAME vers docker-wordpress.kiss.fr => 'kiss.byz','test','docker-wordpress.kiss.fr'
			$response = $ovh->setDomain($domain,$subdomain,$machine->domain);

			//$response = $ovh->domain();

			$logs = array('<pre>'.json_encode($response,JSON_PRETTY_PRINT).'</pre>' );

	
			$history = new History();
			$history->scope = 'docker';
			$history->uid = $environment->id;
			$history->comment = 'Création du host ovh : '.$environment->domain;
			$history->type = 'ovh-save'; 
			$history->save();

			$response['logs'] = implode('<br>',$logs);
	});
	

	Action::register('docker_environment_git_create',function(&$response){

	
			global $myUser,$_,$conf;
			User::check_access('docker','edit');
			require_once(__DIR__.SLASH.'DockerEnvironment.class.php');
			require_once(__DIR__.SLASH.'DockerMachine.class.php');
			require_once(__DIR__.SLASH.'GitLab.class.php');
			Plugin::need('client/Client');
			if(empty($_['id'])) throw new Exception("Environnement obligatoire");
			$environment = DockerEnvironment::provide();
			if(!$environment) throw new Exception("Environnement introuvable");
			
			
			if(empty($environment->client)) throw new Exception("Vous devez spécifier un client pour créer un dépot");
			
			$client = Client::getById($environment->client);
			if(!$client) throw new Exception("Client introuvable");
			
			$git = new Gitlab();
			$git->host = $conf->get('docker_git_host');
			$git->token = $conf->get('docker_git_token');

			$groupName = mb_strtolower($client->getSlug());

			$groups = $git->groups();
			$clientGroup = null;
			

			foreach ($groups as $group) {
				if($group['path'] == $groupName){
					$clientGroup = $group;
					break;
				}
			}
			
			if(!isset($clientGroup)){
				$clientGroup = $git->groupe_save($client->label,$groupName);
			}
			

			$projects = $git->projects();
			foreach ($projects as $project) {
				if($project['name'] == $environment->domain && $project['namespace']['id'] == $clientGroup['id']) throw new Exception("Ce dépot existe déja");
			}

			$project = $git->project_save($clientGroup['id'],$environment->domain,$environment->domain);
			
		
			$environment->git = $project['ssh_url_to_repo'];
			$environment->save();

			
			$logs = array('<pre>'.json_encode($response,JSON_PRETTY_PRINT).'</pre>' );

			$history = new History();
			$history->scope = 'docker';
			$history->uid = $environment->id;
			$history->comment = 'Création du dépot git : '.$environment->domain;
			$history->type = 'git-save'; 
			$history->save();


			$response['logs'] = implode('<br>',$logs);
		
	});







	/** machine / MACHINE **/
	//Récuperation d'une liste de machine
	Action::register('docker_machine_search',function(&$response){
		global $_;
		User::check_access('docker','read');
		require_once(__DIR__.SLASH.'DockerMachine.class.php');
		
		// OPTIONS DE RECHERCHE, A ACTIVER POUR UNE RECHERCHE AVANCEE
		$query = 'SELECT * FROM '.DockerMachine::tableName().' WHERE 1';
		$data = array();
		//Recherche simple
		if(!empty($_['filters']['keyword'])){
			$query .= ' AND label LIKE ?';
			$data[] = '%'.$_['filters']['keyword'].'%';
		}

		//Recherche avancée
		if(isset($_['filters']['advanced'])) filter_secure_query($_['filters']['advanced'],array('label','ip','port','private_key','public_key','domain','sophosReference','description'),$query,$data);

		//Tri des colonnes
		if(isset($_['sort'])) sort_secure_query($_['sort'],array('label','ip','port','private_key','public_key','domain','sophosReference','description'),$query,$data);

		//Pagination
		$response['pagination'] = DockerMachine::paginate(20,(!empty($_['page'])?$_['page']:0),$query,$data);

		$machines = DockerMachine::staticQuery($query,$data,true,0);
		
		foreach($machines as $machine){
			$row = $machine->toArray();
		
			
			$publicKey = File::dir().'docker'.SLASH.'machine'.SLASH.$row['id'].SLASH.'id_rsa.pub';
			$row['public_key'] = file_exists($publicKey)? file_get_contents($publicKey):'';
			
			
			
			$row['description'] = html_entity_decode($row['description']); 
			$response['rows'][] = $row;
		}
		
		/* Mode export */
		if($_['export'] == 'true'){
			$stream = Excel::exportArray($response['rows'],null,'Export');
			File::downloadStream($stream,'export-demandes-'.date('d-m-Y').'.xlsx');
			exit();
		}
		
	});
	
	
	//Ajout ou modification d'élément machine
	Action::register('docker_machine_save',function(&$response){
		global $_;
		User::check_access('docker','edit');
		require_once(__DIR__.SLASH.'DockerMachine.class.php');
		$item = DockerMachine::provide();
		$item->label = $_['label'];
		$item->ip = $_['ip'];
		$item->port = $_['port'];
		$item->domain = $_['domain'];
		$item->sophosReference = $_['sophosReference'];
		$item->description = $_['description'];
		$item->save();
		//Ajout upload Clé privée
		if(!empty($_['private_key']))
			File::save_component('private_key', 'docker/machine/'.$item->id.'/id_rsa');
		//Ajout upload Clé publique
		if(!empty($_['public_key']))
			File::save_component('public_key', 'docker/machine/'.$item->id.'/id_rsa.pub');
		$response = $item->toArray();
	});
	
	

	//Suppression d'élement machine
	Action::register('docker_machine_delete',function(&$response){
		global $_;
		User::check_access('docker','delete');
		require_once(__DIR__.SLASH.'DockerMachine.class.php');
		if(empty($_['id']) || !is_numeric($_['id'])) throw new Exception("Identifiant incorrect");
		DockerMachine::deleteById($_['id']);
	});
	
	
	//machine : Gestion upload Clé privée
	Action::register('docker_machine_private_key',function(&$response){
			File::handle_component(array(
				'namespace' => 'docker', //stockés dans file/docker/*.*
				'access' => 'docker', // crud sur docker,
				'size' => '1000000000', // taille max
				'extension' => 'ppk,id_rsa', // extension
				'storage' => 'docker/machine/{{data.id}}/id_rsa' //chemin complet vers le fichier stocké
			),$response);
	});
	//machine : Gestion upload Clé publique
	Action::register('docker_machine_public_key',function(&$response){
			File::handle_component(array(
				'namespace' => 'docker', //stockés dans file/docker/*.*
				'access' => 'docker', // crud sur docker,
				'size' => '1000000000', // taille max
				'extension' => 'pub,id_rsa', // extension
				'storage' => 'docker/machine/{{data.id}}/id_rsa.pub' //chemin complet vers le fichier stocké
			),$response);
	});

	
//Sauvegarde des configurations de Docker
	Action::register('docker_setting_save',function(&$response){
		global $_,$conf;
		User::check_access('docker','configure');
		//Si input file "multiple", possibilité de normaliser le
		//tableau $_FILES récupéré avec la fonction => normalize_php_files();
		foreach(Configuration::setting('docker') as $key=>$value){
			if(!is_array($value)) continue;
			$allowed[] = $key;
		}
		foreach ($_['fields'] as $key => $value) {
			if(in_array($key, $allowed))
				$conf->put($key,$value);
		}
	});

	



?>