<?php
//For debuging. remove in production
error_reporting(E_ALL);
ini_set("log_errors", true);
ini_set('display_errors', true);
ini_set('error_log', './error.log'); 

define('PATH', __DIR__);
session_start();

require PATH.'/lib/JSONDB.php';
require PATH.'/lib/Template.php';
require PATH.'/lib/Router.php';
require PATH.'/lib/Helpers.php';
require PATH.'/lib/UserManager.php';
require PATH.'/lib/GenericCollectionManager.php';
require PATH.'/lib/AddressbookCollectionManager.php';
require PATH.'/lib/CalendarCollectionManager.php';

$pagevars = [];

$db      = new JSONDB(PATH.'/data');
$userMgr = new UserManager($db);
$cardMgr = new AddressbookCollectionManager($db);
$calMgr  = new CalendarCollectionManager($db);
$tpl     = new Template(PATH.'/template/', [
		'IS_ADMIN' => $userMgr->isAdmin(),
	]);

//GET
Router::add('GET', '/', function(){
	global $userMgr;
	
	if (!$userMgr->isLoggedIn()){
		header("Location: /login");
		exit();
	}

	header("Location: /overview");
});

Router::add('GET', '/login', function(){
	global $tpl;

	$tpl->render('login', [
		'PAGE'		=>	'Login',
	]);
});

Router::add('GET', '/logout', function(){
	global $userMgr;
	$userMgr->logout();
	header("Location: /");
});

Router::add('GET', '/overview', function(){
	global $tpl, $db, $userMgr, $cardMgr, $calMgr;
	$userMgr->checkLoggedIn();

	if (!$userMgr->isAdmin()) {
		$addressbooks = $cardMgr->getCollections('principals/'.$userMgr->getLoggedInAccount()['username']);
		$calendars    = $calMgr->getCollections('principals/'.$userMgr->getLoggedInAccount()['username']);

		foreach ($addressbooks as $addressbook) {
			$tpl->blockAssign('addressbooks', [
					'ID'          => $addressbook['id'],
					'DISPLAYNAME' => $addressbook['displayname'],
					'URI'         => $addressbook['uri'],
				]);
		}

		foreach ($calendars as $calendar) {
			$tpl->blockAssign('calendars', [
					'ID'          => $calendar['id'],
					'DISPLAYNAME' => $calendar['displayname'],
					'URI'         => $calendar['uri'],
				]);
		}

	} else {
		$users = $userMgr->getAll();

		foreach ($users as $user) {
			$tpl->blockAssign('users', [
					'ID'       => $user->id,
					'USERNAME' => $user->username,
					'ACTIVE'   => $user->active,
				]);
		}
	}
	
	$tpl->render('overview', [
		'PAGE'     => 'Overview',
		'USERNAME' => $userMgr->getLoggedInAccount()['username'],
	]);
});

Router::add('GET', '/update', function(){
	global $tpl, $userMgr;
	$userMgr->checkLoggedIn();

	$username = strtolower(trim(Helpers::getVar('username')));

	switch(Helpers::getVar('type')) {
		case 'user':
		
			if (!$userMgr->isAdmin()) {
				header("Location: /overview");
				exit();
			}

			if (!$userMgr->exists($username)) {
				header("Location: /overview");
				exit();				
			}

			$user = $userMgr->get($username);

			$tpl->render('update', [
				'PAGE'       => 'Update User',
				'TYPE'       => 'user',
				'USERNAME'   => $user['username'],
				'ACTIVE'     => $user['active']
			]);

		default:
			header("Location: /overview");
	}
});

//POST 
Router::add('POST', '/login', function(){
	global $tpl, $userMgr;

	try {
		$userMgr->checkLogin(strtolower(trim(Helpers::postVar('username'))), Helpers::postVar('password'));
		header("Location: /overview");
	} catch ( Exception $e ) {
		$tpl->render('login', [
			'PAGE' => 'Login',
			'MSG'  => $e->getMessage(),
		]);		
	}
});

Router::add('POST', '/create', function(){
	global $tpl, $userMgr, $cardMgr, $calMgr;
	$userMgr->checkLoggedIn();

	$username = strtolower(trim(Helpers::postVar('username')));
	$msg      = '';	

	switch(Helpers::postVar('type')) {
		case 'user':
			if (!$userMgr->isAdmin()) {
				header("Location: /overview");
				exit();
			}
				
			try {
				$userMgr->create($username, Helpers::postVar('password'), true);
				$cardMgr->createCollection('principals/'.$username, 'default', ['displayname' => 'Default-Addressbook']);
				$calMgr->createCollection('principals/'.$username, 'default', ['displayname' => 'Default-Calendar']);

				header("Location: /overview");
			} catch ( Exception $e ) {
				$tpl->render('message', [
					'PAGE' => 'Message',
					'MSG'  => $e->getMessage(),
				]);		
			}

		case 'addressbook':
		case 'calendar':
			if ($userMgr->getLoggedInAccount()['username'] !== $username && !$userMgr->isAdmin()) {
				header("Location: /overview");
				exit();
			}

			$uri         = Helpers::postVar('uri');
			$displayname = Helpers::postVar('displayname');

			try {
				if (empty($displayname)) throw new Exception('Displayname can\'t be empty.');
				
				if (empty($uri)) {
					$uri = preg_replace("/[^A-Za-z0-9 ]/", '', $displayname);
				}

				if (empty($uri)) throw new Exception('URI can\'t be empty.');

				if (Helpers::postVar('type') !== 'addressbook') {
					$calMgr->createCollection('principals/'.$username, $uri, ['displayname' => $displayname]);
				} else {
					$cardMgr->createCollection('principals/'.$username, $uri, ['displayname' => $displayname]);
				}

				header("Location: /overview");
			} catch ( Exception $e ) {
				$tpl->render('message', [
					'PAGE' => 'Message',
					'MSG'  => $e->getMessage(),
				]);		
			}

		default:
			header("Location: /overview");
			exit();
	}

	$tpl->render('message', [
		'PAGE'     => 'Oofff',
		'MSG'      => $msg, 
	]);
}); 

Router::add('POST', '/update', function(){
	global $tpl, $userMgr;
	$userMgr->checkLoggedIn();

	$username = strtolower(trim(Helpers::postVar('username')));
	$msg      = '';

	switch(Helpers::postVar('type')) {
		case 'password':
			$password1 = Helpers::postVar('password1');
			$password2 = Helpers::postVar('password2');

			if ($userMgr->getLoggedInAccount()['username'] !== $username && !$userMgr->isAdmin()) {
				header("Location: /overview");
				exit();
			} elseif ($password1 !== $password2) {
				$msg = 'Passwords do not match!';
			} else {
				try {
					$userMgr->updatePassword($username, $password1);
					header("Location: /overview");
					
				} catch (Exception $e) {
					$msg = $e->getMessage();
				}
			}

		case 'user':
			$active = boolval(Helpers::postVar('active'));

			if (!$userMgr->isAdmin()) {
				header("Location: /overview");
				exit();
			}

			try {
				if (!$active) {
					$userMgr->disable($username);
				} else {
					$userMgr->enable($username);
				}

				header("Location: /overview");
					
			} catch (Exception $e) {
				$msg = $e->getMessage();
			}

		default:
			header("Location: /overview");
			exit();
	}

	$tpl->render('message', [
		'PAGE'     => 'Oofff',
		'MSG'      => $msg, 
	]);
});

Router::add('POST', '/delete', function(){
	global $tpl, $userMgr, $cardMgr, $calMgr;
	$userMgr->checkLoggedIn();

	$username = strtolower(trim(Helpers::postVar('username')));
	$msg      = '';
	
	switch (Helpers::postVar('type')) {
		case 'user':
			if ($userMgr->getLoggedInAccount()['username'] !== $username && !$userMgr->isAdmin()) {
				header("Location: /overview");
				exit();
			}

			try {
				$userMgr->delete($username);

				$addressbooks = $cardMgr->getCollections('principals/'.$username);
				$calendars    = $calMgr->getCollections('principals/'.$username);

				foreach ($addressbooks as $addressbook) {
					$cardMgr->deleteCollection($addressbook['id']);
				}

				foreach ($calendars as $calendar) {
					$calMgr->deleteCollection($calendar['id']);
				}

				if ($userMgr->getLoggedInAccount()['username'] !== $username) {
					header("Location: /overview");			
				} else {
					$userMgr->logout();
					header("Location: /");
				}					
			} catch (Exception $e) {
				$msg = $e->getMessage();
			}

		default:
			header("Location: /overview");
			exit();
	}

	$tpl->render('message', [
		'PAGE'     => 'Oofff',
		'MSG'      => $msg, 
	]);
});

Router::pathNotFound(function(){
	header("Loctaion: /");
});

Router::methodNotAllowed(function(){
	header("Loctaion: /");
});

Router::run('/');