<?php 

namespace NPS\Etc;

/**
 * File system related functions
 * @author Lukas Korinek
 */
final class Files 
{
    const EXECUTABLE = 0;
    const WRITEABLE = 1;
    const READABLE = 2;

    /**
     * Normalizes a file path
     * @param string $file File to normalize
     * @param int $type Requested usage type of the file
     * @return string Normalized string
     */
    public static function normalizeFile($file, $type = self::READABLE)
    {

        switch($type)
        {
            case self::READABLE:
            {
                if(!is_readable($file))
                {
                    throw new \InvalidArgumentException('The file is not readable - ' . $file);
                }

                break;
            }
            case self::EXECUTABLE:
            {
                if(!is_executable($file))
                {
                    throw new \InvalidArgumentException('The file is not executable - ' . $file);
                }

                break;
            }
            case self::WRITEABLE:
            {
                if((file_exists($file) && !is_writable($file)) || !is_writable(dirname($file)))
                {
                    throw new \InvalidArgumentException('The file is not writeable - ' . $file);
                }

                touch($file, time(), time());
                chmod($file, 0755);
                break;
            }
            default:
            {
                throw new \InvalidArgumentException('Incorrect file usage type passed');
            }
        }

        return realpath($file);
    }

    /** 
     * Normalizes a directory path
     * @param string $directory Directory to normalize
     * @param int $type Requested usage type of the directory
     * @param bool $create Should attempt to create the directory?
     * @return string
     */
    public static function normalizeDirectory($directory, $type = self::READABLE, $create = false)
    {
        switch($type)
        {
            case self::READABLE:
            {
                if(!is_readable($directory))
                {
                    throw new \InvalidArgumentException('The directory is not readable - ' . $directory);
                }

                break;
            }
            case self::WRITEABLE:
            {
                if($create)
                {
                    if(!is_dir($directory))
                    {
                        if(!@mkdir($directory, 0777, TRUE))
                        {
                            throw new \InvalidArgumentException('The directory couldnt be created - ' . $directory);
                        }
                    }
                }
                else if(!is_dir($directory) || !is_writable($directory))
                {
                    throw new \InvalidArgumentException('The directory is not writeable - ' . $directory);
                }

                break;
            }
            default:
            {
                throw new \InvalidArgumentException('Incorrect directory usage type passed');
            }
        }

        return rtrim(realpath($directory), "/\\");
    }

    /**
     * Recursively removes a directory
     * @param string $path
     */
    public static function rrmdir($path) 
    {
        $path = rtrim($path, "\\/") . '/';

        foreach (glob($path . '*') as $f) 
        {
            $f = basename($f);
            if($f == '..' || $f == '.')
            {
                continue;
            }

            $file = $path . '/' . $f;
            is_dir($file) ? self::rrmdir($file) : unlink($file);
        }
        
        rmdir($path);
   }
}

