<?php

require 'vendor/autoload.php';

function checkDNS($domain)
{
    if (!preg_match('/(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$)/', strtolower($domain))) {
        throw new Exception('not valid domain : "'.$domain.'".');
    }
    $currentip = dns_get_record($domain, DNS_A + DNS_AAAA);
    if (empty($currentip)) {
        throw new Exception('the domain '.$domain.' was not found in DNS record.');
    }
    if ($currentip[0]['ip'] !== $_SERVER['ip4']) {
        throw new Exception('the current ip v4 address of '.$domain.' is '.$currentip[0]['ip'].'. it should be '.$_SERVER['ip4']);
    }
    if ($currentip[1]['ipv6'] !== $_SERVER['ip6']) {
        throw new Exception('the current ip v6 address of '.$domain.' is '.$currentip[1]['ipv6'].'. it should be '.$_SERVER['ip6']);
    }
    return true;
}

function checkIfInstalled($domain)
{
    exec('find /home/* -maxdepth 1 -type d | grep '.$domain, $output);
    if (!empty($output)) {
        throw new Exception('the domain '.$domain.' was already found on the server.');
    }
}

function checkIfUserExist($user)
{
    exec('cut -d: -f1 /etc/passwd | grep '.$user, $output);
    return !empty($output);
}

function generateUserFromDomain($domain, $recursive = null)
{
    if ($recursive == 100) {
        throw new Exception('Too much users found, 100 that is too much for '.$domain);
    }
    $user = str_split(str_replace(['yeswiki.pro', '-', '.'], '', $domain), 30)[0].$recursive;
    // try anthor username if user exists or if reserved name
    if (checkIfUserExist($user) || in_array($user, ['www', 'stats', 'mail', 'sql', 'cron', 'modelesolo', 'modeleferme'])) {
        if ($recursive === null) {
            $recursive = 1;
        }
        $user = generateUserFromDomain($domain, $recursive + 1);
    }
    return $user;
}

function findUserFromExistingDomain($domain)
{
    exec('find /home/* -maxdepth 1 -type d | grep '.$domain, $output);
    if (empty($output)) {
        throw new Exception('the domain '.$domain.' was not found on the server.');
    } else {
        return str_replace(['/home/', '/'.$domain], '', $output[0]);
    }
}

function generatePassword($length = 32, $add_dashes = false, $available_sets = 'luds')
{
    $sets = array();
    if (strpos($available_sets, 'l') !== false) {
        $sets[] = 'abcdefghjkmnpqrstuvwxyz';
    }
    if (strpos($available_sets, 'u') !== false) {
        $sets[] = 'ABCDEFGHJKMNPQRSTUVWXYZ';
    }
    if (strpos($available_sets, 'd') !== false) {
        $sets[] = '23456789';
    }
    if (strpos($available_sets, 's') !== false) {
        $sets[] = '!@#$%&*?';
    }

    $all = '';
    $password = '';
    foreach ($sets as $set) {
        $password .= $set[array_rand(str_split($set))];
        $all .= $set;
    }

    $all = str_split($all);
    for ($i = 0; $i < $length - count($sets); $i++) {
        $password .= $all[array_rand($all)];
    }

    $password = str_shuffle($password);

    if (!$add_dashes) {
        return $password;
    }

    $dash_len = floor(sqrt($length));
    $dash_str = '';
    while (strlen($password) > $dash_len) {
        $dash_str .= substr($password, 0, $dash_len) . '-';
        $password = substr($password, $dash_len);
    }
    $dash_str .= $password;
    return $dash_str;
}

function createSQLUserAndDatabase($user)
{
    $pass = generatePassword();
    exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e \'CREATE DATABASE IF NOT EXISTS '.$user.';\'', $output);
    exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "CREATE USER IF NOT EXISTS \''.$user.'\'@\'localhost\' IDENTIFIED BY \''.$pass.'\';"', $output);
    exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "GRANT ALL PRIVILEGES ON '.$user.'.* TO \''.$user.'\'@\'localhost\';"', $output);
    exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "FLUSH PRIVILEGES;"', $output);
    return ['database' => $user, 'user' => $user, 'password' => $pass];
}

function removeMySQLUserAndDatabase($user)
{
    exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e \'DROP DATABASE IF EXISTS '.$user.';\'', $output);
    exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "DROP USER IF EXISTS \''.$user.'\'@\'localhost\';"', $output);
    exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "FLUSH PRIVILEGES;"', $output);
    return;
}

function createUnixUserWithQuota($user, $quota)
{
    $pass = generatePassword();
    exec('useradd -m -p "'.$pass.'" '.$user, $output);
    exec('setquota -u '.$user.' '.$quota.' '.$quota.' 0 0 -a /dev/loop0', $output);
    // TODO : handle errors
    return ['user' => $user, 'password' => $pass, 'quota' => $quota];
}

function removeUnixUser($user)
{
    exec('deluser --remove-home '.$user, $output);
    // TODO : handle errors
    return;
}

function createNginxConfig($domain, $user, $herseUser, $hersePass)
{
    // Create new Plates instance
    $templates = new League\Plates\Engine('./templates');

    // Render a template
    echo $templates->render('nginx-yeswiki.pro', ['domain' => $domain, 'user' => $user]);

    addHerse($nginxFile, $herseUser, $hersePass);
}

function removeNginxConfig($domain, $user)
{
}

function createPhpFpmConfig($user)
{
}

function removePhpFpmConfig($user)
{
}

function copyYesWikiFiles($domain, $user, $type)
{
    $destDir = '/home'.'/'.$user.'/'.$domain;
    exec('mkdir -p '.$destDir, $output);
    // TODO : handle errors
    return;
}

function copyYesWikiDatabase($user, $type)
{
    $databaseModel = ($type === 'solo') ? $_SERVER['solomodel'] : $_SERVER['fermemodel'];
    exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "DUPLICATE '.$databaseModel.' TO '.$user.';"', $output);
    // TODO : handle errors
    return;
}

function checkHerse($herseUser, $hersePass)
{
    if (empty($herseUser) && empty($hersePass)) {
        return false; // no herse needed
    } elseif (empty($herseUser) || empty($hersePass)) {
        throw new Exception('You need an username AND a password to add a herse.');
    }
    return true; // herse needed
}

function addHerse(&$nginxFile, $herseUser, $hersePass)
{
    if (empty($herseUser) && empty($hersePass)) {
        return ; // no herse needed
    } elseif (empty($herseUser) || empty($hersePass)) {
        throw new Exception('You need an username AND a password to add a herse.');
    } else {
        //add herse to the domain
        echo $nginxFile;
    }
}

function removeYesWiki($domain, $user)
{
    // enlever la db et le user sql
    // enlever la config nginx et la conf php-fpm
    // enlever le user unix et son home
}