<?php

namespace App\Util;

use Exception;

class FileSystem
{
    public static function copy(string $source, string $target, bool $overwrite = true): void
    {
        if (!$overwrite && file_exists($target)) {
            throw new Exception("Target '$target' already exists");
        }

        if (is_dir($source)) {
            mkdir($target, 0777, true);
            foreach (scandir($source) as $item) {
                if ($item == '.' || $item == '..') continue;
                static::copy($source . DIRECTORY_SEPARATOR . $item, $target . DIRECTORY_SEPARATOR . $item, $overwrite);
            }
        } else {
            copy($source, $target);
        }
    }

    public static function createDir(string $dir): void
    {
        if (!file_exists($dir)) {
            mkdir($dir, 0777, true);
        }
    }

    public static function delete(string $path): void
    {
        if (is_dir($path)) {
            foreach (scandir($path) as $item) {
                if ($item == '.' || $item == '..') continue;
                static::delete($path . DIRECTORY_SEPARATOR . $item);
            }
            rmdir($path);
        } elseif (file_exists($path)) {
            unlink($path);
        }
    }

    public static function open(string $file, string $mode)
    {
        return fopen($file, $mode);
    }

    public static function read(string $file): string
    {
        return file_get_contents($file);
    }

    public static function readLines(string $file)
    {
        $handle = fopen($file, 'r');
        if ($handle) {
            while (($line = fgets($handle)) !== false) {
                yield $line;
            }
            fclose($handle);
        }
    }

    public static function rename(string $source, string $target, bool $overwrite = true): void
    {
        if (!$overwrite && file_exists($target)) {
            throw new Exception("Target '$target' already exists");
        }
        rename($source, $target);
    }

    public static function write(string $file, string $content): void
    {
        file_put_contents($file, $content);
    }
}
