<?php

/**
* Directory class 
* 
* @package Sabre
* @subpackage DAV
* @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/) 
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Atmail_Dav_FS_Directory extends Sabre_DAV_FSExt_Directory {

public $path = '';
public $basePath = null;
public $quotaInfo = '';
public $disableListing = false;

function __construct(Sabre_DAV_Auth_Plugin $authPlugin, $path, $basePath = null)
{	

	$this->_authPlugin = $authPlugin;
	$this->path = rtrim($path, '/');
	$this->basePath = rtrim($basePath, '/');
	parent::__construct($this->path);
	
}

public function createFile($name, $data = null) 
{
	$this->updatePath();
	$this->quotaInfo = $this->getQuotaInfo();
	if( (int)$this->quotaInfo[1] < 0 )
		throw new Sabre_DAV_Exception_InsufficientStorage();
	parent::createFile($name, $data);
	//calculate quota again and if over then delete and throw quota exception
	$this->calculateQuotaInfo();

	if( (int)$this->quotaInfo[1] < 0 )
	{
		$newlyCreatedFile = $this->getChild($name);
		$newlyCreatedFile->delete();
		throw new Sabre_DAV_Exception_InsufficientStorage();
	}
}

public function createDirectory($name) 
{
	$this->updatePath();
	$this->getQuotaInfo();

	if( (int)$this->quotaInfo[1] < 0 )
		throw new Sabre_DAV_Exception_InsufficientStorage();
	return parent::createDirectory($name);

}

public function getChild($name) 
{
	$this->updatePath();
	$path = $this->path . '/' . $name;
	
	if (!file_exists($path)) throw new Sabre_DAV_Exception_FileNotFound('File could not be located');
	if ($name=='.' || $name=='..') throw new Sabre_DAV_Exception_Forbidden('Permission denied to . and ..'); 

	if (is_dir($path))
		return new Atmail_Dav_FS_Directory($this->_authPlugin, $path, $this->basePath);
	else
		return new Sabre_DAV_FSExt_File($path);

}

public function childExists($name)
{

    $this->updatePath();
	if ($name=='.' || $name=='..')
        throw new Sabre_DAV_Exception_Forbidden('Permission denied to . and ..');

    $path = $this->path . '/' . $name;
    return file_exists($path);

}

public function getChildren() {

    $this->updatePath();
	$nodes = array();
    foreach(scandir($this->path) as $node) if($node!='.' && $node!='..' && $node!='.sabredav') $nodes[] = $this->getChild($node);
    return $nodes;

}

public function delete() {

    $this->updatePath();
	// Deleting all children
    foreach($this->getChildren() as $child) $child->delete();

    // Removing resource info, if its still around
	if( file_exists($this->path . '/.sabredav') )
		unlink($this->path . '/.sabredav');

    return parent::delete();

	// Removing the directory itself
    rmdir($this->path);



}

private function updatePath()
{

	if( !empty($this->basePath) )
		return; //already done
	$username = $this->_authPlugin->getCurrentUser();
	if( is_numeric($username[0]) )
		$a = 'other';
	else
		$a = $username[0];
	if( $username[1] == '@' )
		$b = 'other';
	else
		$b = $username[1];
	$tmpfolder = $this->path . '/' . $a . '/' . $b . '/' . $username . '/';
	
	if(strpos($tmpfolder, '..') === false && is_dir($tmpfolder))
	{
	
		if(!is_dir($tmpfolder . $this->getName()))
			mkdir($tmpfolder . $this->getName());	
		$this->path = $tmpfolder . $this->getName();
	
	}
	$webFilesPos = strpos($this->path,"webfiles");
	$this->basePath =  substr($this->path, 0, $webFilesPos-1);

}

private function calculateQuotaInfo()
{

	$this->updatePath();
	$quotaB = Atmail_Quota::getTotalQuota(array(Atmail_Quota::ACCOUNT => $this->_authPlugin->getCurrentUser(), Atmail_Quota::TYPE => Atmail_Quota::TYPE_DB))*1024*1024;
	$rootB = self::dirSize($this->basePath);
	$this->quotaInfo = array($rootB,$quotaB-$rootB); //used,free
	if($quotaB == 0)
	{
		// unlimited
		$this->quotaInfo = array($rootB, 0); //used,free
	}
	return $this->quotaInfo;

}

public function getQuotaInfo()
{

	if( $this->quotaInfo == null )
		return $this->calculateQuotaInfo();
	else
		return $this->quotaInfo;

}

private static function dirSize($directory)
{

	$size = 0;
	foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file)
	{
		$size+=$file->getSize();
	}
	return $size;

}

}