<?php
namespace Helpers\Fichier;

use Helpers\Outil\Sql;
use Entity\Model\Paravrac;
use GuzzleHttp\Psr7\CachingStream;
use GuzzleHttp\Psr7\StreamWrapper;
use Helpers\Session\ParseBase1;
use Psr\Http\Message\StreamInterface;

/**
 * @author msa
 *
 *
 *  Helpers permet la gestion repertoire fic_pj et images dans OXADATA/
 */
// phpcs:ignore
class Gestion_Fic_PJ
{
    private \PDO $pdo;
    private string $repertoire_fic_PJ;
    private bool $modeImage;
    private string $racine;
    
    /**
     * @param \PDO $pdo
     * @param boolean $modeImage    // par defaut false (fic_pj) - true (images)
     */
    public function __construct(\PDO $pdo, bool $modeImage = false)
    {
        $this->pdo = $pdo;
        $this->modeImage = $modeImage;
        if ($modeImage) {
            $this->repertoire_fic_PJ = Sql::paravrac($pdo, 'PARAMGEN', 'REPSTKIMGART');
            $this->racine = (new ParseBase1())->getRep()->images;
        } else {
            $this->repertoire_fic_PJ = Sql::paravrac($pdo, 'PARAMGEN', 'REPSTKPJ');
            $this->racine = (new ParseBase1())->getRep()->pj;
        }
    }
    
    private function countFiles() :int
    {
        $urlRepertoire = $this->racine.$this->repertoire_fic_PJ;
        
        if (!file_exists($urlRepertoire)) {
            @mkdir($urlRepertoire, 0700);
        }

        $fi = new \FilesystemIterator($urlRepertoire, \FilesystemIterator::SKIP_DOTS);
        return iterator_count($fi);
    }
    
    /**
     * Permet de mettre a jours le repertoir d'enregistrement
     *
     * Si - de 1000 fichier dans un repertoir on enregistre dans le repertoir courrant
     * Sinon on créer un dossier incrémenté de 1
     *
     */
    public function updateRepertoireSave() :void
    {
        $lastRepertoire = $this->repertoire_fic_PJ;

        if ($this->countFiles()<1000) {
            return;
        }

        if ($lastRepertoire=='') {
            $numeroNewRepertoire = '00001\\';
        } else {
            $explodRepertoire = explode('\\', $lastRepertoire);

            if ($explodRepertoire[1]=='') {
                $numeroNewRepertoire = $lastRepertoire.'0001\\';
            } else {
                if ($explodRepertoire[1]=='100') {
                    $numeroNewRepertoire = (int)$explodRepertoire[0]+1;

                    for ($i=strlen((string)$numeroNewRepertoire); $i<4; $i++) {
                        $numeroNewRepertoire = '0'.$numeroNewRepertoire;
                    }
                    $numeroNewRepertoire = $numeroNewRepertoire.'\\';
                } else {
                    $sousRepertoire = (int)$explodRepertoire[1]+1;

                    for ($i=strlen((string)$sousRepertoire); $i<4; $i++) {
                        $sousRepertoire = '0'.$sousRepertoire;
                    }
                    $numeroNewRepertoire = $explodRepertoire[0].'\\'.$sousRepertoire.'\\';
                }
            }
        }

        $newRepertoire = $this->racine.$numeroNewRepertoire;

        if (@mkdir($newRepertoire, 0700)) {
            $paravrac = new Paravrac($this->pdo);
            if ($this->modeImage) {
                $paravrac->update(['LIB01PARV' => $numeroNewRepertoire], ['TYPEPARV' => 'PARAMGEN', 'CODEPARV' => 'REPSTKIMGART']);
            } else {
                $paravrac->update(['LIB01PARV' => $numeroNewRepertoire], ['TYPEPARV' => 'PARAMGEN', 'CODEPARV' => 'REPSTKPJ']);
            }
            $this->repertoire_fic_PJ = $newRepertoire;
        }
    }
    
    
    //Pour insérer un fichier dans fic_pj, celui ci doit être dans le repertoire TMP
    /**
     *
     * @param string $fileName  : nom du fichier DANS TMP !
     * @param string|StreamInterface $content   : contenu du fichier si création d'un simple fichier text directement dans oxadata
     * @return string|false
     */
    public function insertFichier($fileName, $content = '')
    {
        if ($content) {
            if ($content instanceof StreamInterface) {
                $path = (new ParseBase1())->getRep()->tmp . $fileName;
                $fp = fopen($path, 'w');
                if ($fp === false) {
                    throw new \Exception('fopen failed on "'.$path.'"');
                }
                $b = stream_copy_to_stream(
                    (new StreamWrapper())->getResource($content),
                    $fp
                );
                if ($b == false) {
                    throw new \Exception('stream_copy_to_stream failed');
                }
                $content->rewind();
            } else {
                Fichier::createFichierTmp($fileName, $content);
            }
        }
        
        $this->updateRepertoireSave();
        
        if (rename((new ParseBase1())->getRep()->tmp.$fileName, $this->racine.$this->repertoire_fic_PJ.$fileName)) {
            return $this->repertoire_fic_PJ.$fileName;
        }
        
        return false;
    }
    
    /**
     * @param string $fileSource
     */
    public function deleteFichier($fileSource) :void
    {
        @unlink($this->racine.$fileSource);
    }
    
    /**
     *
     * @param string $fileSource
     * @param string $content   : contenu du fichier si modification d'un simple fichier text directement dans oxadata
     */
    public function updateContenuFichier($fileSource, $content) :void
    {
        Fichier::createFichier($this->racine, $fileSource, $content);
    }
    
    /**
     * Function appeler pour update un fichier enregistré dans oxadate (il delete l'existant et le remplace)
     *
     * @param string  $fileSource
     * @param string $fileName
     * @return string|boolean
     */
    public function updateFicher($fileSource, $fileName)
    {
        $this->deleteFichier($fileSource);
        return $this->insertFichier($fileName);
    }
    
    /**
     * Retourne repertoire de sauvegarde actuelle
     * @return string
     */
    // phpcs:ignore
    public function getRepertoire_fic_PJ()
    {
        return $this->repertoire_fic_PJ;
    }

    /**
     * Create a folder inside the Fic_PJ directory
     * @param string $path  : path to the folder
     * @return int $status : 0 (success) / 1 (fail)
     */
    public static function createFolderOxalinkPages($path)
    {
        if (!is_dir($path)) {
            mkdir($path);
            $status = 0;
        } else {
            $status = 1;
        }

        return $status;
    }
}
