<?php
/**
 * File system.
 * 
 * @package rundiz-downloads
 */


namespace RundizDownloads\App\Libraries;


if (!class_exists('\\RundizDownloads\\App\\Libraries\\FileSystem')) {
    /**
     * File system class.
     */
    class FileSystem
    {


        /**
         * @var string The upload folder name that should matched the plugin slug. Contain only folder name for example `rundiz-downloads`. This constant must be public.
         */
        const UPLOAD_FOLDER_NAME = 'rundiz-downloads';


        /**
         * Delete a file.
         * 
         * @param string $path File path.
         * @return boolean Return true on success, false on failure.
         */
        public function deleteFile($path)
        {
            if (
                is_file($path) &&
                wp_is_writable($path)
            ) {
                return wp_delete_file($path);
            }

            return false;
        }// deleteFile


        /**
         * Get parts of file.
         * 
         * @param string $file URL or full path to file.
         * @return array|false Return file with these keys: 
         *                        name (file name only), 
         *                        ext (file extension only without dot), 
         *                        parent (any parent path or URL without trailing slash), 
         *                        nameext (just file name with extension).
         *                        Return false if failed.
         */
        public function getFilePart($file)
        {
            if (!is_scalar($file)) {
                return false;
            }

            $output = [];
            $output['parent'] = dirname($file);

            $output['nameext'] = str_replace([$output['parent'], '\\', '/'], '', $file);
            $fileExploded = explode('.', $output['nameext']);

            $output['ext'] = (isset($fileExploded[count($fileExploded) - 1]) ? $fileExploded[count($fileExploded) - 1] : '');
            unset($fileExploded[count($fileExploded) - 1]);
            $output['name'] = implode('.', $fileExploded);

            return $output;
        }// getFilePart


        /**
         * Recursively remove directory.<br>
         * This will delete all files and sub folder in it.
         * 
         * @param string $dir Target folder to delete. Such as /path/to/upload/targetfolder. Everything inside 'targetfolder' even files, sub folders will be deleted.
         * @param string $limited_dir Limited to folder. Such as /path/to/upload. Any path that is match to this or upper than this will be skipped.
         */
        public static function rrmDir($dir, $limited_dir)
        {
            if (is_dir($dir)) {
                $objects = scandir($dir);
                foreach ($objects as $object) {
                    if ($dir . DIRECTORY_SEPARATOR . $object === $limited_dir) {
                        return false;
                    } elseif ('.' !== $object && '..' !== $object) {
                        if (wp_is_writable($dir . DIRECTORY_SEPARATOR . $object)) {
                            if (is_dir($dir . DIRECTORY_SEPARATOR . $object)) {
                                static::rrmDir($dir . DIRECTORY_SEPARATOR . $object, $limited_dir);
                            } else {
                                wp_delete_file($dir . DIRECTORY_SEPARATOR . $object);
                            }
                        } else {
                            return false;
                        }
                    }
                }

                if ($dir !== $limited_dir) {
                    rmdir($dir);// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_rmdir
                }
            }
        }// rrmDir


        /**
         * Write a file.
         * 
         * @param string $path Path to file.
         * @param mixed $content File content. If this is not scalar then it will be convert to string using `print_r()` function.
         * @param boolean $append Set to true to append the file content. You have to manually add new line if you want to append to new line.
         * @param int $chmod Change mode number. Read more at http://php.net/manual/en/function.chmod.php
         * @return boolean Return true on success, false on failure.
         * @throws \InvalidArgumentException Throw invalid argument error on wrong type.
         */
        public function writeFile($path, $content, $append = true, $chmod = 0666)
        {
            if (!is_string($path)) {
                throw new \InvalidArgumentException(
                    sprintf(
                        /* translators: %s Argument name. */
                        esc_html__('The %s must be string.', 'rundiz-downloads'), 
                        '$path'
                    )
                );
            }

            if (!is_scalar($content)) {
                $content = trim(print_r($content, true));// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
            }

            if (!is_bool($append)) {
                $append = true;
            }

            if (!is_int($chmod)) {
                $chmod = 0666;
            }

            if (file_exists($path) && false === $append) {
                // if file exists and append is false.
                return false;
            } else {
                if (true === $append) {
                    $flag = FILE_APPEND;
                } else {
                    $flag = 0;
                }
                file_put_contents($path, $content, $flag);// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
                chmod($path, $chmod);// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_chmod

                unset($flag);
                return true;
            }
        }// writeFile


    }// FileSystem
}
