<?php
if (!file_exists("dbindustry_gotowork.php"))
	exit("I am and always will be the optimist. The hoper of far-flung hopes and the dreamer of improbable dreams.");

$myConfig = "config_admin.inc.php";
$applicationPath = "";
$activateAppBuilder = false;
$evadeAuthentication = true; //FIXME: er wordt dus geen automatische SESSION met userid / username geset!
$GLOBALS["DEBUG"] = false;

include("dbindustry_gotowork.php");

// The autoloader
require 'vendor/autoload.php';

/*
 *
 * Onderstaande is de vhost zodat je de DAV vanuit een eigen vhost en root kunt hosten:
 * 
  
 
<VirtualHost 185.41.145.163:443>
        ServerName davstaging.azgbeheer.nl
        ServerAlias azgdavstaging
        DocumentRoot /sites/staging.azgbeheer.nl/htdocs
        ErrorLog /sites/staging.azgbeheer.nl/logs/davstaging_error_log
        CustomLog /sites/staging.azgbeheer.nl/logs/davstaging_access_log combined

        RewriteEngine On
        RewriteRule ^/(.*)$ /davserver.php [L]
        php_flag output_buffering off
        php_flag always_populate_raw_post_data off
        php_flag magic_quotes_gpc off
        php_flag mbstring.func_overload off

        SSLEngine On
        SSLCertificateFile "/etc/ssl/cert/azgbeheer_nl.crt"
        SSLCertificateKeyFile "/etc/ssl/cert/azgbeheer_nl.key"
        SSLCertificateChainFile "/etc/ssl/cert/PositiveSSL.ca-bundle"
        <FilesMatch "\.(cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
        </FilesMatch>
        BrowserMatch "MSIE [2-5]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
</VirtualHost>
 * 
 */

/*
 * HELPER KLASSE
 */
class DocDavHelper 
{
	public static function getDocTree()
	{
		static $result = false;
		
		if (!empty($result)) {
			return $result;
		}
		
		$Category = new cp_doc_category();

		$Permission = new cp_doc_permission();
		$permissions = $Permission->getPermissions($_SESSION["userID"]);
		
		$sql = "SELECT * FROM `cp_doc_category` ORDER BY `linenumber` ASC";
		$result = $Category->dbinstance->getData($sql);
		
		$sql = "SELECT * FROM `cp_doc_category` ORDER BY `linenumber` DESC";
		$categories = $Category->dbinstance->getData($sql);
		
		foreach ($result as $key => $values)
		{
			$text = $values["description"];
			$start = false;
			foreach ($categories as $category)
			{
				if ($category["id"] == $values["id"])
				{
					$indent = $category["indent"];
					$start = true;
					continue;
				}
				if ($start && $category["indent"] < $indent)
				{
					$text = $category["description"]."/".$text;
					$indent = $category["indent"];
				}
				if ($start && $category["indent"] == 0)
				{
					break;
				}
			}
			$result[$key]["node"] = "documentbeheer/".$text;
		}

		foreach ($result as $key => $values)
		{
			foreach ($permissions as $permission)
			{
				if ($permission["category_id"] === $values["id"])
				{
					if ($permission["manager"] || $permission["owner"] || $permission["contributor"] || $permission["receiver"])
					{
						continue;
					}
					else
					{
						unset($result[$key]);
					}
				}
			}
		}
		
		return $result;
	}
	
	public static function getFiles($categoryID)
	{
		$Doc = new cp_doc();
		$DocLink = new cp_doc_link();
		$DocLinkType = new cp_doc_link_type();

		static $files = [];
		
		if (isset($files[$categoryID]))
		{
			return $files[$categoryID];
		}
		
		//FIXME: hoeft niet met een hele renderende getList (kost teveel performance)
		$GLOBALS["ADAPTERS"]->setAdapterValue("internal", "cp_doc_overview_for_category", "category_id", $categoryID);
		$GLOBALS["ADAPTERS"]->setAdapterValue("internal", "cp_doc_overview_for_category", "template", 0);
		$docs = (new cp_doc_overview_for_category)->getList(new jobList(["class" => "cp_doc_overview_for_category", "action" => "view", "type" => "list"]));
		$GLOBALS["ADAPTERS"]->deleteAdapterValue("internal", "cp_doc_overview_for_category", "category_id");
		
		foreach ($docs as $doc)
		{
			if ($doc["category_id"][0] == $categoryID)
			{
				$file = unserialize(base64_decode($Doc->getActiveFile($doc["-dbIndustryPK_id"])));
				//				vd($file);
				if (!empty($file)) // Voor docs zonder active asset
				{
					$files[$categoryID][] = ["doc_id" => $doc["-dbIndustryPK_id"], "download_name" => $file["download_name"]];
				}
				//				$files[] = $doc["name"];
				//				$files[] = $doc["-dbIndustryPK_id"];
			}
		}
		//		vd($files);
		return $files[$categoryID];
	}
}


class CentralePostAuth extends Sabre\DAV\Auth\Backend\AbstractBasic
{
	protected $realm = "centralepost/dav";
	
	protected function validateUserPass($username, $password)
	{
		return (new dbindustry_user())->getAllowedUserByNameAndPassword($username, $password);
	}
}

class CentralePostProtectedCollection extends Sabre\DAV\Collection
{
	protected $paths = 
		[	
			[	
				"group" => "opleidingen-staf",
				"path" => "../dav/opleidingen-staf"
			],
			[
				"group" => "dav_rijinstructeur",
				"path" => "../dav/rijinstructeur"
			]
		];
	
	protected $authPlugin;

	function getChildren() {
		
		$username = str_replace("principals/", "", $this->authPlugin->getCurrentPrincipal());
		$userID = (new dbindustry_user())->getUserByName($username)["id"];
		
		$result = [];
		
		foreach ($this->paths as $path)
		{
			if ((new dbindustry_usergroup())->isUserMemberOfGroupByName($userID, $path["group"]))
			{
				$result[] = new Sabre\DAV\FS\Directory($path["path"]);
			}
		}

		if (empty($result)) 
		{
			$result = false;
		}
		
		return $result;
	}

	function getName() {
		return 'protected';
	}

	function __construct($authPlugin) {
		$this->authPlugin = $authPlugin;
	}
}

class CentralePostCollection extends Sabre\DAV\Collection
{
	protected $path = '../dav/rijinstructeur';

	protected $authPlugin;
	
	function getChildren() {
		$username = str_replace("principals/", "", $this->authPlugin->getCurrentPrincipal());
		$userID = (new dbindustry_user())->getUserByName($username)["id"];
		if (!(new dbindustry_usergroup())->isUserMemberOfGroupByName($userID, "dav_rijinstructeur"))
		{
			return false;	
		}
		
		$result = [];
		$result[] = new Sabre\DAV\FS\Directory($this->path);
		return $result;
	}
	
	function getName() {
		return 'protected';
	}	
	
	function __construct($authPlugin) {
		$this->authPlugin = $authPlugin;
	}
}

class CentralePostDocCollection extends Sabre\DAV\Collection {

	protected $myPath;

	protected $authPlugin;
	
	protected $list;
	
	function __construct($path, $authPlugin = false) {
		$this->myPath = $path;
		$this->authPlugin = $authPlugin;
	}

	protected function getFile($name)
	{
		$Doc = new cp_doc();
		$doc = $Doc->findParts(["name" => $name])[0];
		$file = (new cp_doc())->getActiveFile($doc["id"]);
		$file = unserialize(base64_decode($file));
		return $file;
	}	
	
	function getChildren()
	{
		$username = str_replace("principals/", "", $this->authPlugin->getCurrentPrincipal());
		$userID = (new dbindustry_user())->getUserByName($username)["id"];

		//PAS OP: doordat authentication wordt ge-evade werken we dus ZONDER userID
		$_SESSION["userID"] = $userID;
		
		$children = array();
//		vd($this);
		$path = $this->myPath;
//	vd($_SERVER);
		$tree = DocDavHelper::getDocTree();
//vd($path);		
		if ($path != "/") {
			$path = "documentbeheer/".$path."/";
		}
//vd($path);
//vd($tree);

		//IDEE: tijdelijke tabel met alle gegenereerde namen (of huidige actieve naam opslaan in cp_doc zelf, net zoals versie, dus niet steeds zelf hoeven te genereren
		
		foreach ($tree as $key => $values)
		{
			//			vd($values["node"]);
			if (strpos($values["node"], $path) !== false &&
					substr_count($path, "/") === substr_count($values["node"], "/"))
			{
				$children[] = $this->getChild($values["node"]);
			}
		}

		foreach ($tree as $key => $values)
		{
			if ($values["node"]."/" === $path)
			{
				$files = DocDavHelper::getFiles($values["id"]);
				foreach ($files as $file)
				{
					$name = $file["download_name"];
					$children[] = new MyFile($path.$name);
				}
			}
		}

		return $children;
	}
	
	function getChild($name) {
		
	//	vd("mypath:".$this->myPath);
//vd($this);
	//	vd("name:".$name);

		
		if ($name[0] === '.')  
		{
			throw new Sabre\DAV\Exception\NotFound('Access denied');
		}
		
		$filename = substr($this->myPath, strrpos($this->myPath, "/") + 1);
		$dir = str_replace($filename, "", $this->myPath);
	//	vd("filename:".$filename);
//		vd("dir:".$dir);
		
		// Als mypath + name alleen maar een volledige categorie is dan return een collection
		// als mypath + name niet kan worden gevonden in de categorieen dan is het een file
		
		$tree = DocDavHelper::getDocTree();
		foreach ($tree as $key => $values)
		{
			if (strpos($name, "documentbeheer/") === 0) 
			{
				$search = $name;
			}
			else 
			{
				$search = "documentbeheer/".($this->myPath === "/" ? "" : $this->myPath."/").$name;
			}
//			vd("search:".$search);
			if ($values["node"] === $search)
			{
	//			vd("node:".$values["node"]);
				if ($this->myPath != "/") {
					$name = $this->myPath."/".$name;
				}
				return new CentralePostDocCollection($name, $this->authPlugin);
			}
		}

		foreach ($tree as $key => $values)
		{
			//				vd("documentbeheer/".$this->myPath);
			if ($values["node"] === "documentbeheer/".$this->myPath)
			{
				//					vd($values["node"]);
				$files = DocDavHelper::getFiles($values["id"]);
				foreach ($files as $file)
				{
					if ($file["download_name"] === $name)
					{
						return new MyFile($this->myPath."/".$name);
					}
				}
			}
		}
		
		throw new Sabre\DAV\Exception\NotFound('File not found');
		
		
		return false;
		
		if (strpos($name, ".") !== false) //FIXME: als er een puntje in staat is het een bestand, anders een directory...
		{
			$tree = DocDavHelper::getDocTree();
			foreach ($tree as $key => $values)
			{
//				vd("documentbeheer/".$this->myPath);
				if ($values["node"] === "documentbeheer/".$this->myPath)
				{
//					vd($values["node"]);
					$files = DocDavHelper::getFiles($values["id"]);
					foreach ($files as $file)
					{
						if ($file["download_name"] === $name)
						{
							vd($this->myPath."/".$name);
							return new MyFile($this->myPath."/".$name);
						}
					}
				}
			}
		}
		
		throw new Sabre\DAV\Exception\NotFound('File not found');
		
		return false;
		
		if ($this->myPath != "/") {
			$name = $this->myPath."/".$name;
		}
		
		return new CentralePostDocCollection($name, $this->authPlugin);
		
		/*
		$DocAsset = new cp_doc_asset();
		$assets = $DocAsset->findParts(["status" => "active"]);
		foreach ($assets as $asset)
		{
			$activeFile = unserialize(base64_decode($asset["file"]));
			$path = $activeFile["location"].$activeFile["filename"];
			if ($activeFile["name"] === $name)
			{
				break;
			}
		}
		
		// We have to throw a NotFound exception if the file didn't exist
		if (!file_exists($path)) {
			throw new Sabre\DAV\Exception\NotFound('The file with name: ' . $name . ' could not be found');
		}
		// Some added security
		if ($name[0]=='.')  throw new Sabre\DAV\Exception\NotFound('Access denied');

		if (is_dir($path)) {
			return new CentralePostDocCollection($path);
		} else {
			return new MyFile($name);
		}
		*/
	}

	function childExists($name) {
		return true;
		return file_exists($this->myPath . '/' . $name);
	}

	function getName() {
		
		if ($this->myPath == "/") {
			$result .= "documentbeheer";
		} else {
			$result .= $this->myPath;
		}
		
		return basename($result);
		
	}
}

class MyFile extends Sabre\DAV\File {
	
	protected $myPath;
	
	protected function getFileName()
	{
		//vd($this->myPath);
		
		$Doc = new cp_doc();
		
		$file = unserialize(base64_decode($Doc->getActiveFile($this->myPath)));
		return $file;
		
		$doc = $Doc->findParts(["name" => $this->myPath])[0];
		$file = (new cp_doc())->getActiveFile($doc["id"]);
		$file = unserialize(base64_decode($file));
		return $file;
	}
	
	protected function getRealFile()
	{	
//		vd($this->myPath);
		
		static $fileInfo = [];
		
		if ($fileInfo[$this->myPath])
		{
			return $fileInfo[$this->myPath];
		}
		
		$filename = substr($this->myPath, strrpos($this->myPath, "/") + 1);
		$dir = str_replace($filename, "", $this->myPath);
	//	vd($filename);
		//vd($dir);
		
		if (strpos($dir, "documentbeheer/") === false)
		{
			$dir = "documentbeheer/".$dir;
		}
		
		$Doc = new cp_doc();

		$tree = DocDavHelper::getDocTree();
		foreach ($tree as $key => $values)
		{
			if ($values["node"]."/" === $dir)
			{
				$files = DocDavHelper::getFiles($values["id"]);
				foreach ($files as $file)
				{
					if ($file["download_name"] === $filename)
					{
						$fileInfo[$this->myPath] = unserialize(base64_decode($Doc->getActiveFile($file["doc_id"])));
//						vd($fileInfo);
					}
				}
			}
		}
		
		return $fileInfo[$this->myPath];
		
		$DocAsset = new cp_doc_asset();
		$assets = $DocAsset->findParts(["status" => "active"]);
		foreach ($assets as $asset)
		{
			$activeFile = unserialize(base64_decode($asset["file"]));
			if ($activeFile["name"] === $this->myPath)
			{
				break;
			}
		}
		return $activeFile;
	}
	
	function __construct($myPath) {
//		vd($myPath);
		$this->myPath = $myPath;
	}
	
	function getName() {
		
		$filename = substr($this->myPath, strrpos($this->myPath, "/") + 1);
		$dir = str_replace($filename, "", $this->myPath);

		return $filename;
		
		return $this->myPath;
		
//		vd($this->myPath);
		
		$file = $this->getFileName();
		return $file["download_name"];
	}
	
	function get() {
		$file = $this->getRealFile();
		return fopen($file["location"].$file["filename"],'r');
	}
	
	function getContentType() {
		$file = $this->getRealFile();
		return $file["type"];
	}
	
	function getSize() {
		/*
		if (strpos($this->myPath, "/") === false) { //FIXME: deze hele klasse wordt aangeroepen MET en ZONDER een hele path
//			vd($this->myPath);
//			vd($this);
			return true;
		}
		*/
		$file = $this->getRealFile();
		return $file["size"];
		vd($file);
		return filesize($file["location"].$file["filename"]);
	}
	
	function getETag() {
		$file = $this->getRealFile();
		$result = '"' . md5_file($file["location"].$file["filename"]) . '"';
		return $result;
	}
}

$authBackend = new CentralePostAuth;
$authPlugin = new Sabre\DAV\Auth\Plugin($authBackend);

// Now we're creating a whole bunch of objects
$public = new Sabre\DAV\FS\Directory('../dav/public');

$tree = [
	new CentralePostDocCollection("/",$authPlugin),
	new CentralePostDocCollection("BO&O/Communicatie/Formats en sjablonen",$authPlugin),
	$public,
	new CentralePostProtectedCollection($authPlugin),
//	new CentralePostCollection($authPlugin)
];

// The server object is responsible for making sense out of the WebDAV protocol
$server = new Sabre\DAV\Server($tree);

// If your server is not on your webroot, make sure the following line has the
// correct information
$server->setBaseUri('/');

// The lock manager is reponsible for making sure users don't overwrite
// each others changes.
$lockBackend = new Sabre\DAV\Locks\Backend\File('../dav/data/locks');
$lockPlugin = new Sabre\DAV\Locks\Plugin($lockBackend);
$server->addPlugin($lockPlugin);

// This ensures that we get a pretty index in the browser, but it is
// optional.
$server->addPlugin(new Sabre\DAV\Browser\Plugin());

$server->addPlugin($authPlugin);

//FIXME: locking ook mogelijk maken zie: https://github.com/fruux/sabre-dav/issues/471

// All we need to do now, is to fire up the server
$server->exec();