<?php

class File {
	private $_path = null;
	private $_headers = [];

	public function __construct($path = null) {
		if ($path instanceof File) {
			$this->_path = $path->path();
		}

		$this->_path = $path;
	}

	public function basename() { 
		return pathinfo($this->_path, PATHINFO_BASENAME); 
	}

	public function dirname() { 
		return pathinfo($this->_path, PATHINFO_DIRNAME); 
	}

	public function extension() { 
		return pathinfo($this->_path, PATHINFO_EXTENSION); 
	}

	public function filename() { 
		return pathinfo($this->_path, PATHINFO_FILENAME); 
	}

	public function delete() { $this->unlink(); }
	public function unlink() {
		unlink($this->_path);
	}

	public function content() {
		return get_file_contents($this->_path);
	}

	public function emit() {
		$headers = $this->_headers;

		$headers['ETag'] = "\"" . $this->hash() . "\"";

		foreach ($headers as $k=>$v) {
			header($k . ": " . $v);
		}
		readfile($this->_path);
	}

	public function set_headers($data) {
		$this->_headers = $data;
	}

	public function get_headers() {
		return $this->_headers;
	}

	public function set_header($k, $v) {
		$this->_headers[trim($k)] = trim($v);
	}

	public function exists() {
		return file_exists($this->_path);
	}

	public function size() {
		return stat($this->_path)["size"];
	}

	public function path() {
		return $this->_path;
	}

	public function mime() {
		if (!file_exists($this->_path)) {
			return false;
		}
		return mime_content_type($this->_path);
	}

	public function __toString() {
		return $this->_path;
	}

	public function parent() {
		$p = $this->dirname();
		if ($p == "") {
			return false;
		}
		return new File($p);
	}

	public function mkdir() {
		$p = $this->parent();
		if ($p) {
			if (!$p->exists()) {
				$p->mkdir();
			}
		}

		if (!$this->exists()) {
			mkdir($this->_path, 0777);
		}
	}

	public function hash($type = "sha256") {
		return hash_file($type, $this->_path);
	}

	public function rename($to, $over=false) {
		if ($to == $this->path()) return false;
		if ((!$over) && file_exists($to)) return false;
		copy($this->path(), $to);
		if (!file_exists($to)) return false;
		unlink($this->path());
		$this->_path = $to;
		return true;
	}

	public function get_chunk($from, $len) {
		$f = fopen($this->_path, "r");
		fseek($f, $from);
		$data = fread($f, $len);
		fclose($f);
		return $data;
	}
}
