<?php

namespace kernel\helpers;

use FilesystemIterator;
use ZipArchive;

class Files
{
    public function copy_folder($d1, $d2, int $permissions = 0775, bool $recursive = true): void
    {
        if (is_dir($d1)) {
            if (!file_exists($d2)){
                $old_mask = umask(0);
                $_d2 = mkdir($d2, permissions: $permissions, recursive: $recursive);
                umask($old_mask);
                if (!$_d2) {
                    return;
                }
            }

            $d = dir($d1);
            while (false !== ($entry = $d->read())) {
                if ($entry != '.' && $entry != '..') {
                    $this->copy_folder("$d1/$entry", "$d2/$entry");
                }
            }
            $d->close();
        } else {
            copy($d1, $d2);
            chmod($d2, permissions: $permissions);
        }
    }

    public function copyKernelFolder($d1, $d2, int $permissions = 0775, bool $recursive = true): void
    {
        if (is_dir($d1)) {
            if (!file_exists($d2)){
                $old_mask = umask(0);
                $_d2 = mkdir($d2, permissions: $permissions, recursive: $recursive);
                umask($old_mask);
                if (!$_d2) {
                    return;
                }
            }

            $d = dir($d1);
            while (false !== ($entry = $d->read())) {
                if ($entry != '.' && $entry != '..' && $entry != 'app_modules') {
                    $this->copyKernelFolder("$d1/$entry", "$d2/$entry");
                }
            }
            $d->close();
        } else {
            copy($d1, $d2);
            chmod($d2, permissions: $permissions);
        }
    }

    public function recursiveRemoveDir($dir): void
    {
        $includes = new FilesystemIterator($dir);
        foreach ($includes as $include) {
            if(is_dir($include) && !is_link($include)) {
                $this->recursiveRemoveDir($include);
            }
            else {
                unlink($include);
            }
        }
        rmdir($dir);
    }

    public function recursiveRemoveKernelDir(): void
    {
        $includes = new FilesystemIterator(KERNEL_DIR);
        foreach ($includes as $include) {
            if ($include->getFilename() === 'app_modules') continue;

            if(is_dir($include) && !is_link($include)) {
                $this->recursiveRemoveDir($include);
            }
            else {
                unlink($include);
            }
        }
    }

    public function pack(string $source, string $destination/*, bool $include_source = true*/): void
    {
        $zip = new ZipArchive();
        $zip->open($destination, ZipArchive::CREATE | ZipArchive::OVERWRITE);

        if (is_file($source)) {
            $zip->addFile(basename($source));
        }

        if (is_dir($source)) {
            $this->recursiveAddFile($zip, $source);
        }

        $zip->close();
    }

    public static function uploadByUrl(string $url, string $uploadDir = RESOURCES_DIR . "/upload"): void
    {
        $file_name = basename($url);
        file_put_contents($uploadDir . '/' . $file_name, file_get_contents($url));
    }

    private function recursiveAddFile(ZipArchive $zip, string $dir, string $folder = ''): void
    {
        $includes = new FilesystemIterator($dir);

        foreach ($includes as $include) {
            if(is_dir($include)) {
                if ($include->getFilename() === 'app_modules') continue;

                $tmpFolder = $folder . '/' . $include->getFilename();
                $this->recursiveAddFile($zip, $include, $tmpFolder);
            }
            if (is_file($include)) {
                $zip->addFile($include->getPathName(), $folder . "/" . $include->getFilename());
            }
        }
    }

}