<?php

class file
{
    public static function record(array $_temp, string $_folderFiles = DIR_DATAS_FILES)
    {
        $md5 = md5_file($_temp["tmp_name"]);

        if(self::findM5($md5) == FALSE){
            if (copy($_temp["tmp_name"], $_folderFiles . $md5)) {
                db::query("INSERT INTO " . DB_T_FILES . " (id, name, size, id_user) VALUES (:id, :name, :size, :id_user)");
                db::bind(':id', $md5);
                db::bind(':name', $_temp['name']);
                db::bind(':size', $_temp['size']);
                db::bind(':id_user', session::getId());
    
                try {
                    db::execute();
                    return $md5;
                } catch (Exception $ex) {
                    unlink($_folderFiles . $md5);
                    alert::recError("Erreur #record sur l'import du fichier " . $_temp['name']);
                    return FALSE;
                }
            }
        } else {
            alert::recError("Erreur #record ce fichier a déjà été importé : " . $_temp['name']);
            return FALSE;
        }
    }

    public static function findM5(string $_md5)
    {
        db::query("SELECT "
            . "IF(" . DB_T_FILES . ".name IS NOT NULL, TRUE, FALSE) AS exist "
            . "FROM " . DB_T_FILES . " "
            . "WHERE " . DB_T_FILES . ".id = :md5");
        db::bind(':md5', $_md5);
        $return = db::single();
        return ($return == TRUE) ? TRUE : FALSE;
    }

    public static function delete(string $_id = NULL, string $_folderFiles = DIR_DATAS_FILES)
    {
        if (isset($_id) and $_id != NULL and file_exists($_folderFiles . $_id)) {
            if (unlink($_folderFiles . $_id)) {
                db::query("DELETE FROM " . DB_T_FILES . " WHERE id = :id");
                db::bind(':id', $_id);

                try {
                    db::execute();
                    return TRUE;
                } catch (Exception $ex) {
                    alert::recError("Erreur lors de la désindexation du fichier");
                    return FALSE;
                }
            } else {
                alert::recError("Erreur sur la suppression du fichier");
                return FALSE;
            }
        } else {
            return FALSE;
        }
    }

    public static function download(string $_id, string $_folderFiles = DIR_DATAS_FILES)
    {
        if (file_exists($_folderFiles . $_id)) {
            return $_folderFiles . $_id;
        } else {
            return FALSE;
        }
    }

    public static function cleanFilesByOrder(string $_path, int $_nbFiles = 5)
    {
        $return = TRUE;
        $cpt = 0;
        $files = array();
        $dir = new DirectoryIterator($_path);
        $blackList = array(
            ".",
            "..",
            "index.html",
            "index.php"
        );

        foreach ($dir as $fileinfo) {
            $files[$fileinfo->getMTime()] = $fileinfo->getFilename();
        }

        krsort($files);

        foreach ($files as $file) {
            if (!in_array($file, $blackList)) {
                if ($cpt++ >= $_nbFiles) {
                    $return = (unlink($_path . $file)) ? TRUE : FALSE;
                }
            }
        }

        return $return;
    }

    public static function cleanAllFiles(string $_path)
    {
        $return = TRUE;
        $dir = new DirectoryIterator($_path);
        $blackList = array(
            ".",
            "..",
            "index.html",
            "index.php"
        );

        foreach ($dir as $fileinfo) {
            if (!in_array($fileinfo->getFilename(), $blackList)) {
                $return = (unlink($_path . $fileinfo->getFilename())) ? TRUE : FALSE;
            }
        }
        return $return;
    }

    public static function cleanFilesByTime(string $_path, int $_limitTime = 24 * 3600) // 24*3600 pour une journée
    {
        if ($handle = opendir($_path)) {
            while (false !== ($file = readdir($handle))) {
                $filelastmodified = filemtime($_path . $file);
                if ((time() - $filelastmodified) > $_limitTime) {
                    unlink($_path . $file);
                }
            }
            closedir($handle);
        }
    }

    public static function copyFolder(string $_folder, string $_target)
    {
        if ($dir = opendir($_folder)) {
            mkdir($_target);
            while (($file = readdir($dir))) {
                if (($file != '.') && ($file != '..')) {
                    if (is_dir($_folder . '/' . $file)) {
                        self::copyFolder($_folder . '/' . $file, $_target . '/' . $file);
                    } else {
                        copy($_folder . '/' . $file, $_target . '/' . $file);
                    }
                }
            }
            closedir($dir);
        }
    }

    public static function deleteFolder(string $_dir)
    {
        if (is_dir($_dir)) {
            $command = "rm -r " . $_dir;
            try {
                system($command);
                return TRUE;
            } catch (Exception $ex) {
                return FALSE;
            }
        }
    }


    public static function zip(string $_dir, string $_name)
    {
        $zip = new ZipArchive();
        $zip_name = $_name . ".zip";
        $zip->open($zip_name, ZipArchive::CREATE);
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($_dir), RecursiveIteratorIterator::LEAVES_ONLY);
        foreach ($files as $file) {
            if (!$file->isDir()) {
                $filePath = $file->getRealPath();
                $relativePath = substr($filePath, strlen($_dir));
                $zip->addFile($filePath, $relativePath);
            }
        }
        $zip->close();
        return $zip_name;
    }

    public static function unzip(string $_zip, string $_target)
    {
        if (is_file($_zip)) {
            $zipInfo = pathinfo($_zip);
            if ($zipInfo["extension"] == "zip") {
                $command = "unzip -q " . $_zip . " -d " . $_target . $zipInfo["filename"];
                try {
                    system($command);
                    return $zipInfo["filename"];
                } catch (Exception $ex) {
                    return FALSE;
                }
            }
        }
        return FALSE;
    }

    public static function sizeFolder(string $_rep)
    {
        $Racine = opendir($_rep);
        $Taille = 0;
        while ($Dossier = readdir($Racine)) {
            if ($Dossier != '..' and $Dossier != '.') {
                //Ajoute la taille du sous dossier
                if (is_dir($_rep . '/' . $Dossier)) $Taille += self::sizeFolder($_rep . '/' .
                    $Dossier);
                //Ajoute la taille du fichier
                else $Taille += filesize($_rep . '/' . $Dossier);
            }
        }
        closedir($Racine);
        return $Taille;
    }
}
