<?php

use Claromentis\Core\Acl\PermOClass;
use Claromentis\Core\DAL\Exceptions\TransactionException;
use Claromentis\Projects\ProjectsRepository;

if (!defined('INSTALL_PROGRESS'))
	die("This file cannot be executed directly");

if (!isset($installer))
	throw new Exception("Install options are not defined");

/** @var $installer \Claromentis\Setup\SetupFacade */

$admin_panel = $installer->GetAdminPanelCreator();
$admin_panel->Create('projects', "/projects/admin", array('name' => "Projects", 'css_class' => 'glyphicons-project'));

$plugins = $installer->GetPluginsRepository();
$plugins->Add('projects', '\Claromentis\Projects\ProjectsPlugin', ['dmsv']);

use Claromentis\Core\Services;
use Claromentis\Menu\Infobar\MenuItemApplication;
use Claromentis\Menu\Infobar\MenuItemRepository;

$menu = Services::I()->{MenuItemRepository::class};
$menu->save(new MenuItemApplication('projects', 'Projects', '/projects/'));

// Add metadata set and fields for homepage component
$db = $installer->GetDb();
$existing_metadata_sets = array();
[$md_sets_exist] = $db->query_row("SELECT COUNT(1) FROM metadata_set WHERE set_type=int:set_type", \Claromentis\Projects\Repository\ProjectRepository::METADATA_SET_PROJECTS_PROJECT);

if (!$md_sets_exist)
{
	$db->DisableTokenCheck();

	$mds = new MetaDataSet();
	$mds->name = 'Projects';
	$mds->set_type = \Claromentis\Projects\Repository\ProjectRepository::METADATA_SET_PROJECTS_PROJECT;
	$mds->Save();

	$db->EnableTokenCheck();
}

// Add file storage for anything uploaded to the project description
$cdn = Claromentis\Core\Services::I()->GetCDN();
if (!$cdn->IsDir('projects'))
	$cdn->CreateDir('projects');
if (!$cdn->IsDir('projects/description'))
	$cdn->CreateDir('projects/description');


// Add default roles
// Constant values at the time of the migration
$PROJECT_AGGREGATION = 121;

$VIEW_PROJECT = 1;
$VIEW_TEAM = (1 << 1);
$VIEW_TASKS = (1 << 2);
$VIEW_ALL_TASKS = (1 << 3);
$UPDATE_OWN_TASK_STATUS = (1 << 4);
$ADD_TASK = (1 << 5);
$EDIT_OWN_TASK = (1 << 6);
$EDIT_ANY_TASK = (1 << 7);
$VIEW_DISCUSSION = (1 << 8);
$PARTICIPATE_IN_DISCUSSION = (1 << 9);
//$EDIT_OWN_DISCUSSION = (1 << 12);
$EDIT_ANY_DISCUSSION = (1 << 13);
$VIEW_FILE = (1 << 14);
$ADD_FILE = (1 << 15);
$VIEW_PRIVATE_FILE = (1 << 16);
$MANAGE_FILES = (1 << 18);
$EDIT_PROJECT_PROPERTIES = (1 << 19);
$DELETE_PROJECT = (1 << 21);
$TEAM_NOTIFICATIONS = (1 << 22);
$TEAM_MEMBER = (1 << 23);
$EXTENDED_NOTIFICATIONS = (1 << 24);
$ADD_PROJECT_UPDATE = (1 << 25);
$MANAGE_OWN_TOPICS = (1 << 26);

$pm_rights = $VIEW_PROJECT
	| $VIEW_TEAM
	| $VIEW_TASKS
	| $VIEW_ALL_TASKS
	| $UPDATE_OWN_TASK_STATUS
	| $ADD_TASK
	| $EDIT_OWN_TASK
	| $EDIT_ANY_TASK
	| $VIEW_DISCUSSION
	| $PARTICIPATE_IN_DISCUSSION
	| $EDIT_ANY_DISCUSSION
	| $VIEW_FILE
	| $ADD_FILE
	| $VIEW_PRIVATE_FILE
	| $MANAGE_FILES
	| $EDIT_PROJECT_PROPERTIES
	| $DELETE_PROJECT
	| $TEAM_NOTIFICATIONS
	| $TEAM_MEMBER
    | $EXTENDED_NOTIFICATIONS
	| $ADD_PROJECT_UPDATE
	| $MANAGE_OWN_TOPICS;
$senior_team_rights = $VIEW_PROJECT
	| $VIEW_TEAM
	| $VIEW_TASKS
	| $VIEW_ALL_TASKS
	| $UPDATE_OWN_TASK_STATUS
	| $ADD_TASK
	| $EDIT_OWN_TASK
	| $VIEW_DISCUSSION
	| $PARTICIPATE_IN_DISCUSSION
	| $VIEW_FILE
	| $ADD_FILE
	| $VIEW_PRIVATE_FILE
	| $MANAGE_FILES
	| $TEAM_NOTIFICATIONS
	| $TEAM_MEMBER
	| $ADD_PROJECT_UPDATE
	| $MANAGE_OWN_TOPICS;
$team_rights = $VIEW_PROJECT
	| $VIEW_TEAM
	| $VIEW_TASKS
	| $VIEW_ALL_TASKS
	| $UPDATE_OWN_TASK_STATUS
	| $ADD_TASK
	| $EDIT_OWN_TASK
	| $VIEW_DISCUSSION
	| $PARTICIPATE_IN_DISCUSSION
	| $VIEW_FILE
	| $ADD_FILE
	| $VIEW_PRIVATE_FILE
	| $TEAM_NOTIFICATIONS
	| $TEAM_MEMBER
	| $MANAGE_OWN_TOPICS;
$senior_client_rights = $VIEW_PROJECT
	| $VIEW_TEAM
	| $VIEW_TASKS
	| $UPDATE_OWN_TASK_STATUS
	| $ADD_TASK
	| $EDIT_OWN_TASK
	| $VIEW_DISCUSSION
	| $PARTICIPATE_IN_DISCUSSION
	| $VIEW_FILE
	| $ADD_FILE
	| $TEAM_NOTIFICATIONS
	| $TEAM_MEMBER
	| $MANAGE_OWN_TOPICS;
$client_rights = $VIEW_PROJECT
	| $VIEW_TEAM
	| $VIEW_TASKS
	| $UPDATE_OWN_TASK_STATUS
	| $EDIT_OWN_TASK
	| $VIEW_DISCUSSION
	| $PARTICIPATE_IN_DISCUSSION
	| $VIEW_FILE
	| $ADD_FILE
	| $TEAM_NOTIFICATIONS
	| $TEAM_MEMBER
	| $MANAGE_OWN_TOPICS;
$viewer_rights = $VIEW_PROJECT
	| $VIEW_TEAM
	| $VIEW_TASKS
	| $VIEW_DISCUSSION
	| $VIEW_FILE;

// Make a list
$old_roles = [
	1 => [
		'name' => 'PM',
		'rights' => $pm_rights
	],
	2 => [
		'name' => 'Senior Team',
		'rights' => $senior_team_rights
	],
	3 => [
		'name' => 'Team',
		'rights' => $team_rights
	],
	4 => [
		'name' => 'Senior Client',
		'rights' => $senior_client_rights
	],
	5 => [
		'name' => 'Client',
		'rights' => $client_rights
	],
	6 => [
		'name' => 'Viewer',
		'rights' => $viewer_rights
	]
];

// Add new default roles
$order = 0;

list($roles_exist) = $db->query("SELECT COUNT(*) FROM acl_role WHERE aggregation=int:agg AND object_id=0", $PROJECT_AGGREGATION)->fetchAllValues();

if (!$roles_exist)
{
	foreach ($old_roles as $role)
	{
		$db->query("INSERT INTO acl_role (aggregation, object_id, name, position, rights, read_only) VALUES (int:aggr, int:default_id, str:role_name, int:order, int:rights, 0)",
			$PROJECT_AGGREGATION,
			0,
			$role['name'],
			$order++,
			$role['rights']);
	}
}

try
{
	$db->DoTransaction(function () use ($installer) {
		$db = $installer->GetDb();

		$projects_localizations = [
			'en' => 'Projects',
			'us' => 'Projects',
			'ru' => 'Проекты',
			'fr' => 'Projets',
			'de' => 'Projekte',
			'br' => null,
			'es' => null,
			'nl' => null,
			'cz' => null,
			'pl' => 'Projekty',
			'gr' => null,
			'ar' => null,
			'ku' => null,
			'hu' => 'Projektek',
			'uz' => 'Loyihalar'
		];

		$result = $db->query("SELECT variables.var_value, ERMS_file_plan.id FROM variables LEFT JOIN ERMS_file_plan ON variables.var_value = ERMS_file_plan.id WHERE var_name eq:str:projects_root_folder_variable", ProjectsRepository::PROJECTS_ROOT_FOLDER);
		$row    = $result->fetchRow();

		// If the Projects' Root Folder exists.
		if (isset($row[1]))
		{
			return;
		}

		$projects_root_folder_defined = false;
		// If the Project's Root Folder has been defined, but does not exist.
		if (isset($row[0]))
		{
			$projects_root_folder_defined = true;
		}

		// The Projects' Root Folder does not exist.
		$config           = $installer->GetConfigFull();
		$default_language = $config->Get('cfg_default_language');
		if (!is_string($default_language) || !isset($projects_localizations[$default_language]))
		{
			$default_language = 'en';
		}

		$projects_root_folder_name = $projects_localizations[$default_language];

		$result = $db->query("SELECT id FROM ERMS_file_plan WHERE title eq:str:projects_root_folder_name", $projects_root_folder_name);
		$row    = $result->fetchRow();

		// If the Folder with the chosen name doesn't exist, create it
		if (!isset($row[0]))
		{
			// Create the ID for the Unified Permissions object.
			$db->query("INSERT INTO perm_objects (dummy) VALUES (0)");
			$perm_id = (int) $db->insertId();

			$perm_oclass_id_rights = [
				PermOClass::INDIVIDUAL     => ['perm_owner_id' => 1, 'rights' => 8],
				PermOClass::ALL            => ['perm_owner_id' => 0, 'rights' => 1],
				PERM_OCLASS_PARENT         => ['perm_owner_id' => 0, 'rights' => 1],
				PERM_OCLASS_SECURITY_LEVEL => ['perm_owner_id' => 0, 'rights' => 1]
			];

			// Set the Unified Permissions Object's Permissions.
			foreach ($perm_oclass_id_rights as $perm_oclass_id => $object_rights)
			{
				$db->query("INSERT INTO permissions (
						class_id,
						object_id,
						perm_owner_class_id,
						perm_owner_id,
						rights
					) VALUES (
						int:class_id,
						int:id,
						int:oclass,
						int:oid,
						int:perms
					)",
					PERM_CLASS_UNIFIED,
					$perm_id,
					$perm_oclass_id,
					$object_rights['perm_owner_id'],
					$object_rights['rights']
				);
			}

			// Create Folder.
			$db->query("INSERT INTO ERMS_file_plan (
					title,
					date_created,
					date_last_modified,
					aggregation,
					creator,
					perm_id
				) VALUES (
					str:title,
					int:date_created,
					int:date_last_modified,
					int:aggregation,
					int:creator,
					int:perm_id
				)",
				$projects_root_folder_name,
				date('YmdHis'),
				date('YmdHis'),
				AGGREGATION_FOLDER,
				1,
				$perm_id
			);
			$folder_id = (int) $db->insertId();
		} else
		{
			$folder_id = (int) $row[0];
		}

		if ($projects_root_folder_defined)
		{
			$query = "UPDATE variables SET var_value=str:value WHERE var_name eq:str:name";
		} else
		{
			$query = "INSERT INTO variables (var_value, var_name) VALUES (str:value, str:name)";
		}

		$db->query($query, $folder_id, ProjectsRepository::PROJECTS_ROOT_FOLDER);
	});
} catch (TransactionException $exception)
{
	$installer->log("Failed to create Projects' Root Folder.");

	throw $exception;
}
