<?php namespace Intellex\Upload;

use Intellex\Filesystem\File;

/**
 * A representation of an uploaded file.
 *
 * @class
 */
class UploadFile extends File {

	/** @var string Additional information about the file. */
	private $extra;

	/**
	 * Construct a File from the a path.
	 *
	 * @param string $path A path to where the file is located.
	 */
	public function __construct($path) {
		parent::__construct($path);

		// Extra
		$this->extra = $this->calculateExtra();
	}

	/**
	 * Get extra parameters for the file.
	 */
	private function calculateExtra() {
		if ($this->exists()) {
			$mime = $this->getMimetype();
			if (strpos($mime, '/')) {
				list($major, $minor) = explode('/', $this->getMimetype());
				switch ($major) {
					case 'image':
						list($width, $height) = getimagesize($this->getPath());
						return "{$width}x{$height}px";

					case 'text':
						switch ($minor) {
							case 'plain':
								return sizeof(file($this->getPath())) . ' lines';
						}
						break;
				}
			}
		}

		return '';
	}

	/**
	 * Make sure the the file has the unique filename in its directory.
	 */
	public function assureUniqueFilename() {
		$count = 1;
		$base = $this->getParent()->getPath() . static::DS . $this->getFilename();
		while ($this->exists()) {
			$this->init($base . '-' . $count++ . '.' . $this->getExtension());
		}

		return $this;
	}

	/**
	 * Check if supplied string is a valid filename.
	 *
	 * @param string $filename The filename to test.
	 *
	 * @return boolean True if supplied string can be used as filename, false otherwise.
	 */
	public static function isValidFilename($filename) {
		return preg_match('~^[^<>:"\|\?\*]+$~ i', $filename);
	}

	/** @return string Additional information about the file. */
	public function getExtra() {
		return $this->extra;
	}

	/**
	 * Get all information about the file, as an array.
	 *
	 * @return array The file details.
	 */
	public function details() {
		return [
			'extension' => $this->getExtension(true),
			'mime' => $this->getMimeType(),
			'extra' => $this->getExtra(),
			'size' => $this->getSize(),
		];
	}

}
