<?php

if(isset($_GET['action']) && $_GET['action'] =='check_connection'){
	$response = array();

	require_once(__DIR__.'/connector/'.$_GET['connector'].'.class.php');
	$connector = $_GET['connector'];
	$connectionString = $connector::connection;
    foreach ($_GET as $key => $value) {
         $connectionString = str_replace('{{'.$key.'}}',$value,$connectionString);
    }

    $connectionString = str_replace('{{ROOT}}',dirname(__FILE__).DIRECTORY_SEPARATOR,$connectionString);
	try{
		$connection = new PDO($connectionString, $_GET['login'], $_GET['password'],$connector::pdo_attributes());
    }catch(Exception $e){
    	$response['error'] = 'Connexion impossible : '.$e->getMessage();
    }
	echo json_encode($response);
	exit();
}

try {

	/*
	Page customizable depuis n'importe quel app.json de plugin via la mention :

	"install":  "Install.class.php",

	cette classe située au sein du plugin peut contenir les méthodes suivantes

	css : chemin relatif au plugin d'un fichier css custom d'install
	js : chemin relatif au plugin d'un fichier js custom d'install
	post_install : méthode contenant le code qui doit s'executer en fin d'installation.
	pre_install : méthode en début d'installation.

	*/


	date_default_timezone_set('Europe/Paris');
	mb_internal_encoding('UTF-8');
	require_once(__DIR__.'/function.php');
	spl_autoload_register('app_autoloader');

	$_ = array_map('secure_user_vars', array_merge($_POST, $_GET));
	require_once('class/Plugin.class.php');
	$entityFolder = __DIR__.'/class/';


	if(file_exists(__DIR__.DIRECTORY_SEPARATOR.'.git') && !file_exists(__DIR__.DIRECTORY_SEPARATOR.'.git'.DIRECTORY_SEPARATOR.'.htaccess')){
		file_put_contents(__DIR__.DIRECTORY_SEPARATOR.'.git'.DIRECTORY_SEPARATOR.'.htaccess', 'Require all denied');
	}

	$custom = null;
	//Recherche de custom install dans les plugins
	foreach(glob(__DIR__.DIRECTORY_SEPARATOR.'plugin'.DIRECTORY_SEPARATOR.'*'.DIRECTORY_SEPARATOR.'app.json') as $app){
		$manifest = json_decode(file_get_contents($app),true);
		if(!$manifest || !isset($manifest['install'])) continue;
		$custom = array();
		$custom['plugin'] =  'plugin/'.basename(dirname($app)).'/';
		$custom['pluginPath'] =  __DIR__.DIRECTORY_SEPARATOR.'plugin'.DIRECTORY_SEPARATOR.basename(dirname($app)).DIRECTORY_SEPARATOR;

		$custom['class'] = basename(str_replace('.class.php', '', $manifest['install']));
		$custom['classPath'] = $custom['pluginPath'].$custom['class'].'.class.php';
		require_once($custom['classPath']);
	}





	/*
	Installation en mode cli, exemple :
	php install.php "{\"connector\":\"Mysql\",\"host\":\"mysql-host\",\"login\":\"root\",\"password\":\"root\",\"name\":\"hackpoint\",\"root\":\"http:\/\/127.0.0.1\/hackpoint\"}"
	*/
	if(php_sapi_name() == 'cli'){
		echo 'Headless install...'.PHP_EOL;
		$parameters = json_decode($argv[1],true);
		echo 'Parameters: '.PHP_EOL;
		print_r($parameters);
		echo 'Installing... '.PHP_EOL;
		install_core($parameters,$custom);
		echo 'Installation done. '.PHP_EOL;
		exit();
	}

	?>

	<!DOCTYPE html>
	<html lang="fr">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<meta name="description" content="">
		<meta name="author" content="">
		<link rel="icon" type="image/png" href="favicon.png" />

		<title>Installateur</title>

		<!-- Bootstrap core CSS -->
		<link href="css/bootstrap.min.css" rel="stylesheet">
		<!-- Font awesome -->
		<link rel="stylesheet" href="css/fontawesome-all.min.css">
		<!-- Custom styles for this template -->
		<link href="css/main.css" rel="stylesheet">
		<?php



		if(!empty($custom['class']) && method_exists($custom['class'], 'css')): ?>
			<link href="<?php echo $custom['plugin'].$custom['class']::css(); ?>" rel="stylesheet">
		<?php endif; ?>
		<style>
			body{
				background: #f5f5f5;
			}
		</style>

	</head>

	<body>
		<!-- Fixed navbar -->
		<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
			<a class="navbar-brand" href="index.php"><img style="max-height: 40px;" src="img/logo/default-logo.png"> Installation</a>
			<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
				<span class="navbar-toggler-icon"></span>
			</button>

		</nav>

		<!-- Begin page content -->
		<div class="container">
		<?php
		$entities = array();

		foreach(glob(__DIR__.'/connector/*.class.php') as $classFile){
			require_once($classFile);
			$className = str_replace('.class.php','',basename($classFile));
			$entities[$className] = $className::label.' - '.$className::description;
		}

		//check prerequisite
		if(file_exists(__DIR__.'/constant.php')) throw new Exception('Le script est déja installé, pour recommencer l\'installation, supprimez le fichier constant.php');
		if(!is_writable (__DIR__)) throw new Exception('Le dossier '.__DIR__.' doit être accessible en ecriture, merci de taper la commande linux <br/><code>sudo chown -R www-data:www-data '.__ROOT__.'</code><br/> ou de régler le dossier en écriture via votre client ftp');
		if(!file_exists(__DIR__.'/file')) mkdir(__DIR__.'/file',0755,true);
		if(!file_exists(__DIR__.'/file/avatar')) mkdir(__DIR__.'/file/avatar',0755,true);

		//if(!extension_loaded('gd') || !function_exists('gd_info'))  throw new Exception('L\'extension php GD2  est requise, veuillez installer GD2 (sous linux : <code>sudo apt-get install php5-gd && service apache2 restart</code>)');
		//if(!in_array('sqlite',PDO::getAvailableDrivers())) throw new Exception('Le driver SQLITE est requis, veuillez installer sqlite3 (sous linux : <code>sudo apt-get install php5-sqlite && service apache2 restart</code>)');

		if(isset($_['connector'])){
			install_core($_,$custom);
			?>

			<div class="alert alert-success alert-dismissable">
				<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
				<strong>Succès!</strong> La base est bien installée, l'utilisateur par défaut est <code>admin:admin</code>, pensez à changer le mot de passe rapidemment. <br>
			</div>
			<a class="btn btn-primary" href="index.php">Revenir à l'index</a>
			<?php
		} else {

			$root = 'http'.((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')|| $_SERVER['SERVER_PORT'] == 443?'s':'').'://'.$_SERVER['HTTP_HOST'].($_SERVER['SERVER_PORT']==80?'':':'.$_SERVER['SERVER_PORT']).$_SERVER['REQUEST_URI'];
			$root = str_replace("/install.php", "", $root );
			$parts = explode('?',$root);
			$root = array_shift($parts);

			if(!empty($custom['class']) && method_exists($custom['class'], 'pre_form') ) $custom['class']::pre_form();
			?>

			<div class="row justify-content-md-center">
				<form class="col-md-6 mt-3" action="install.php" method="POST">
					<h3>Installation</h3>
					<p class="text-muted">Merci de bien vouloir remplir les champs ci-dessous</p>


					<div class="input-group mb-3">
						<div class="input-group-prepend">
					    	<label class="input-group-text" for="connector">Type de base</label>
					    </div>
						<select class="form-control" id="connector" name="connector" onchange="window.location='install.php?sgbd='+$(this).val()">
							<option value="">-</option>
							<?php foreach($entities as $class=>$label): ?>
								<option <?php echo (isset($_['sgbd']) && $_['sgbd']==$class ? 'selected="selected"': '') ?> value="<?php echo $class ?>"><?php echo $label; ?></option>
							<?php endforeach; ?>
						</select>
					</div>

					<?php if(isset($_['sgbd']) && $_['sgbd']!=''):
						require_once(__DIR__.'/connector/'.$_['sgbd'].'.class.php');
						foreach($_['sgbd']::fields() as $field): ?>

							<div class="input-group mb-3">
								<div class="input-group-prepend">
							    	<label class="input-group-text"  for="<?php echo $field['id']; ?>"><?php echo $field['label']; ?></label>
							    </div>


							<?php if(!isset($field['comment'])): ?><small><?php echo $field['comment']; ?></small><br/><?php endif; ?>
							<input type="text" class="form-control" value="<?php echo $field['default']; ?>" name="<?php echo $field['id']; ?>" id="<?php echo $field['id']; ?>"/></div>
						<?php endforeach;  ?>

						<div class="input-group mb-3">
							<div class="input-group-prepend">
						    	<label class="input-group-text" for="root">Adresse web</label>
						    </div>
							<input type="text" class="form-control " name="root" id="root" value="<?php echo $root; ?>"/><br/>
						</div>


						<div class="btn btn-primary right" onclick="$(this).addClass('btn-preloader');$(this).parent().get(0).submit()"><i class="far fa-check-circle"></i> Installer</div>
						<div class="btn btn-dark right mr-2 btn-test" onclick="check_connection()"><i class="far fa-check-circle"></i> Tester la connexion</div>

						</div>

					<?php endif; ?>
				</form>
			</div>
			<?php

			if(!empty($custom['class']) && method_exists($custom['class'], 'post_form') ) $custom['class']::post_form();
		}
	} catch (Exception $e) { ?>
			<div class="alert alert-danger">
				<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
				<strong>Oops!</strong> <?php echo $e->getMessage().' - '.$e->getFile().' L'.$e->getLine().'<hr/><pre>'.$e->getTraceAsString().'</pre>';
				?>
			</div>
		<?php
	} ?>
	</div>

	<!-- Bootstrap core JavaScript -->
	<!-- Placed at the end of the document so the pages load faster -->
	<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
	<script>window.jQuery || document.write('<script src="js/vendor/jquery.min.js"><\/script>')</script>
	<script src="js/vendor/popper.min.js"></script>
	<script src="js/bootstrap.min.js"></script>
	<script src="js/vendor/mustache.min.js"></script>
	<script src="js/plugins.js"></script>
	<script src="js/main.js"></script>
	<?php if(!empty($custom['class']) && method_exists($custom['class'], 'js') ): ?>
		<link href="<?php echo $custom['plugin'].$custom['class']::js(); ?>" rel="stylesheet">
	<?php endif; ?>
	<script type="text/javascript">
			function check_connection(){
				var data = $('form').toJson();
				data.action = 'check_connection';
				$('.btn-test').addClass('btn-preloader');
				$.getJSON({
					url :'install.php',
					data : data,
					success:function(response){
						setTimeout(function(){
							$('.btn-test').removeClass('btn-preloader');
						},500);
						if(response.error){
							$.message('error',response.error);
						}else{
							$.message('success','Connecté à la base avec succès');
						}
					}
				});
			}
	</script>
</body>
</html>

<?php

function install_core($parameters,$custom){
	$constantStream = file_get_contents(__DIR__.'/constant-sample.php');
	$enablePlugins = array('fr.core.factory','fr.core.dashboard','fr.core.notification','fr.core.navigation');

	if(!isset($parameters['host'])) $parameters['host'] = '';
	if(!isset($parameters['login'])) $parameters['login'] = '';
	if(!isset($parameters['password'])) $parameters['password'] = '';
	if(!isset($parameters['database'])) $parameters['database'] = '';

	$cryptKey = base64_encode(time().$parameters['login'].mt_rand(0,1000));
	$tags = array_merge($parameters,array(
		'cryptKey' => $cryptKey
	));
	foreach ($tags as $key => $value) {
		$constantStream = str_replace("{{".$key."}}",$value,$constantStream);
	}
	file_put_contents(__DIR__.DIRECTORY_SEPARATOR.'constant.php',$constantStream);
	require_once(__DIR__.DIRECTORY_SEPARATOR.'constant.php');

	if(!file_exists(File::core())) mkdir(File::core(),0755,true);
	require_once(__ROOT__.'class'.SLASH.'Entity.class.php');

	if(!empty($custom['class']) && method_exists($custom['class'], 'pre_install') ) $custom['class']::pre_install();

	//install entities
	Entity::install(__ROOT__.'class');

	global $conf,$myUser;
	$conf = new Configuration();
	$conf->getAll();

	//create firm
	$firm = new Firm();
	$firm->label = 'Établissement';
	$firm->description = 'Établissement par défaut';
	$firm->save();

	/* RANKS */
	//create admin rank
	$superAdmin = new Rank();
	$superAdmin->label = 'Super Admin';
	$superAdmin->description = 'Dispose de tous les accès';
	$superAdmin->superadmin = true;
	$superAdmin->save();

	//create all anonymous rank
	$anonymous = new Rank();
	$anonymous->label = 'Tout le monde - Anonyme';
	$anonymous->description = 'Utilisateur non connecté à la plateforme';
	$anonymous->superadmin = false;
	$anonymous->save();

	//create all connected rank
	$connected = new Rank();
	$connected->label = 'Tout le monde - Connecté';
	$connected->description = 'Utilisateur connecté à la plateforme';
	$connected->superadmin = false;
	$connected->save();

	//create default user
	$admin = new User();
	$admin->login = 'admin';
	$admin->password = User::password_encrypt('admin');
	$admin->firstname = 'Administrateur';
	$admin->name = 'Principal';
	$admin->superadmin = 1;
	$admin->state = User::ACTIVE;
	$admin->meta = json_encode($admin->meta);
	$admin->save();

	//create ufr
	$userfirmrank = new UserFirmRank();
	$userfirmrank->user = $admin->login;
	$userfirmrank->firm = $firm->id;
	$userfirmrank->rank = $superAdmin->id;
	$userfirmrank->save();

	$admin->loadRanks();
	$_SESSION['currentUser'] = serialize($admin);
	$myUser = $admin;

	$scopes = array();
	Plugin::callHook('section',array(&$scopes));
	foreach($scopes as $scope=>$description){
		$right = new Right();
		$right->targetUid = $superAdmin->id;
		$right->targetScope = 'rank';
		$right->scope = $scope;
		$right->read = true;
		$right->edit = true;
		$right->delete = true;
		$right->configure = true;
		$right->save();
	}

	//droits sur les rangs créés only par superadmin
	foreach (array($superAdmin->id,$anonymous->id,$connected->id) as $rankId) {
		$right = new Right();
		$right->scope = 'rank';
		$right->uid = $rankId;
		$right->read = 1;
		$right->edit = 1;
		$right->delete = 1;
		$right->configure = 1;
		$right->recursive = 1;
		$right->targetScope = 'rank';
		$right->targetUid = $superAdmin->id;
		$right->save();
	}

	//Activation des plugins par défaut
	foreach ($enablePlugins as  $plugin) {
		if(!Plugin::exist($plugin)) continue;
		Plugin::state($plugin,true);
	}
	$states = Plugin::states();

	//Activation des plugins pour les établissements
	foreach(Firm::loadAll() as $firm){
		foreach ($enablePlugins as  $plugin) {
			if(!Plugin::exist($plugin)) continue;
			$firms = $states[$plugin];
			$key = array_search($firm->id, $firms);
			$firms[] = $firm->id;
			$states[$plugin] = array_values($firms);
			Plugin::states($states);
		}
	}
	if(!empty($custom['class']) && method_exists($custom['class'], 'post_install') ) $custom['class']::post_install();
}
