<commit_before><?php

namespace Parvula\Core;

use Parvula\Core\Exception\IOException;

/**
 * Files System
 *
 * @package Parvula
 * @version 0.5.0
 * @since 0.1.0
 * @author <NAME>
 * @license MIT License
 */
class FilesSystem {

	/**
	 * @var string
	 */
	private $prefixPath;

	/**
	 * Constructor
	 *
	 * @param string $prefixPath
	 */
	function __construct($prefixPath = '.') {
		$this->prefixPath = rtrim($prefixPath) . '/';
	}

	/**
	 * Check if file exists
	 *
	 * @param string $filename File name
	 * @return boolean If file exists
	 */
	public function exists($filename) {
		return file_exists($this->prefixPath . $filename);
	}

	/**
	 * Check if it is a directory
	 *
	 * @param string $dirname Directory name
	 * @return boolean If direcorty exists
	 */
	public function isDir($dirname) {
		return is_dir($this->prefixPath . $dirname);
	}

	/**
	 * Read data from file
	 *
	 * @param string $filename File name
	 * @param callable ($fn) Apply function to file data
	 * @param boolean ($eval) Evaluate PHP
	 * @throws IOException If the file does not exists
	 * @return mixed File data
	 */
	public function read($filename, $fn = null, $eval = false) {
		if(!$this->exists($filename)) {
			throw new IOException("File '$filename' does not exist.");
		}

		if($eval) {
			ob_start();
			include $this->prefixPath . $filename;
			$data = ob_get_clean();
		} else {
			$data = file_get_contents($this->prefixPath . $filename);
		}

		if($fn !== null) {
			return $fn($data);
		} else {
			return $data;
		}
	}

	/**
	 * Write data to file
	 *
	 * @param string $filename File name
	 * @param mixed $data
	 * @param callable ($fn) Apply function to data
	 * @throws IOException if file is not writable
	 */
	public function write($filename, $data, $fn = null) {
		if($fn !== null) {
			$data = $fn($data);
		}

		if(false === @file_put_contents($this->prefixPath . $filename, $data)) {
			throw new IOException("File '$filename' is not writable.");
		}
	}

	/**
	 * Delete file
	 *
	 * @param string $filename File to delete
	 * @throws IOException If the file does not exists
	 * @return boolean If filename is deleted
	 */
	public function delete($filename) {
		if(!$this->exists($filename)) {
			throw new IOException("File '$filename' not found", 1);
		}

		return unlink($this->prefixPath . $filename);
	}

	/**
	 * Check if file is writable
	 *
	 * @param string $filename File name
	 * @return boolean If file is writable
	 */
	public function isWritable($filename) {
		return is_writable($this->prefixPath . $filename);
	}

	/**
	 * List files recursively in a directory
	 *
	 * @param string $directory Directory to list recursively
	 * @param boolean $showHiddenFiles True to list hidden files
	 * @param callable $fn Callback function for each item $fn($key, $val)
	 * @return array Return array of files<commit_msg>add `rename` method<commit_after><?php

namespace Parvula\Core;

use Parvula\Core\Exception\IOException;

/**
 * Files System
 *
 * @package Parvula
 * @version 0.5.0
 * @since 0.1.0
 * @author <NAME>
 * @license MIT License
 */
class FilesSystem {

	/**
	 * @var string
	 */
	private $prefixPath;

	/**
	 * Constructor
	 *
	 * @param string $prefixPath
	 */
	function __construct($prefixPath = '.') {
		$this->prefixPath = rtrim($prefixPath, '/') . '/';
	}

	/**
	 * Check if file exists
	 *
	 * @param string $filename File name
	 * @return boolean If file exists
	 */
	public function exists($filename) {
		return file_exists($this->prefixPath . $filename);
	}

	/**
	 * Check if it is a directory
	 *
	 * @param string $dirname Directory name
	 * @return boolean If direcorty exists
	 */
	public function isDir($dirname) {
		return is_dir($this->prefixPath . $dirname);
	}

	/**
	 * Read data from file
	 *
	 * @param string $filename File name
	 * @param callable ($fn) Apply function to file data
	 * @param boolean ($eval) Evaluate PHP
	 * @throws IOException If the file does not exists
	 * @return mixed File data
	 */
	public function read($filename, $fn = null, $eval = false) {
		if(!$this->exists($filename)) {
			throw new IOException("File '$filename' does not exist.");
		}

		if($eval) {
			ob_start();
			include $this->prefixPath . $filename;
			$data = ob_get_clean();
		} else {
			$data = file_get_contents($this->prefixPath . $filename);
		}

		if($fn !== null) {
			return $fn($data);
		} else {
			return $data;
		}
	}

	/**
	 * Write data to file
	 *
	 * @param string $filename File name
	 * @param mixed $data
	 * @param callable ($fn) Apply function to data
	 * @throws IOException if file is not writable
	 */
	public function write($filename, $data, $fn = null) {
		if($fn !== null) {
			$data = $fn($data);
		}

		if(false === @file_put_contents($this->prefixPath . $filename, $data)) {
			throw new IOException("File '$filename' is not writable.");
		}
	}

	/**
	 * Delete file
	 *
	 * @param string $filename File to delete
	 * @throws IOException If the file does not exists
	 * @return boolean If filename is deleted
	 */
	public function delete($filename) {
		if(!$this->exists($filename)) {
			throw new IOException("File '$filename' not found", 1);
		}

		return unlink($this->prefixPath . $filename);
	}

	/**
	 * Check if file is writable
	 *
	 * @param string $filename File name
	 * @return boolean If file is writable
	 */
	public function isWritable($filename) {
		return is_writable($this->prefixPath . $filename);
	}

	/**
	 * Rename file
	 *
	 * @param string $oldName Old file name
	 * @param string $newName New file name
	 * @return boolean
	 */
	public function rename($oldName, $newName) {
		return rename($this->prefixPath . $oldName, $this->prefixPath . $newName);
	}

	 * List files recursively in a directory
	 *
	 * @param string $directory Directory to list recursively
	 * @param boolean $showHiddenFiles True to list hidden files
	 * @param callable $fn Callback function for each item $fn($key, $val)
	 * @return array Return array of files
{'fraction_non_alphanumeric': 0.13891227479373633, 'fraction_numerical': 0.00235729920862098, 'mean_word_length': 3.291907514450867, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3684158', 'n_tokens_mistral': 2010, 'n_tokens_neox': 1794, 'n_words': 592}