<?php

namespace App\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\Common\Collections\ArrayCollection;

class ProjectRepository extends EntityRepository
{

    // getProjectsGroup
    // $user                = l'utilisateur en cours    
    // $groupid             = id du group 
    
    public function getProjectsGroup($user,$groupid)
    {
        $projectsshared=$this->createQueryBuilder('project')
                ->from('App\Entity\Group','g')
                ->andWhere('g MEMBER OF project.groups')
                ->andWhere('g.id=:id')
                ->setParameter('id',$groupid)
                ->addOrderBy('project.name', 'ASC')                    
                ->getQuery()->getResult();

        
        // Permission sur les projects
        if($projectsshared) {
            foreach($projectsshared as $projectshared) {
                $projectshared->setCanupdate(false);
                $projectshared->setCanadd($this->getInwriter($user,$projectshared));
            }
        }

        return $projectsshared;
    }

    // getProjectsUser
    // $user                   = l'utilisateur en cours
    // &$projectsuser          = les projects de l'utilisateur
    // &$projects              = les projects système de l'utilistauer
    // &$projectsshared        = les projects partagées pour l'utilisateur
    
    public function getProjectsUser($user,&$projectsuser,&$projectsadmin,&$projectsshared)
    {
        // Profilage
        $roles=($user?$user->getRoles():["ROLE_ANONYME"]);
        $groups=($user?$user->getGroups():[]);

        // Récupération des projects de l'utilisateur
        $projectsuser=[];
        if($user) {
            $qb = $this->createQueryBuilder('project');
            $qb ->where("project.user=:user")
                ->setParameter("user",$user)
                ->addOrderBy('project.name', 'ASC');
            $projectsuser=$qb->getQuery()->getResult();
        }
        
        // Permission sur les projects
        if($projectsuser) {
            foreach($projectsuser as $projectuser) {
                $projectuser->setCanupdate(true);
                $projectuser->setCanadd(true);
            }
        }

        // projects partagées
        $projectsshared=[];

        // Initialisation du calcul des projects
        $projectsadmin=new ArrayCollection();

        // Récupération des projects par rôles
        foreach($roles as $role) {
            $qb = $this->createQueryBuilder("project");
            $qb ->where($qb->expr()->like('project.roles', $qb->expr()->literal("%$role%")))
                ->andWhere("project.user != :user or project.user is null")
                ->setParameter('user',$user);
            
            $projectsroles=$qb->getQuery()->getResult();
            foreach($projectsroles as $projectrole) {
                if(!$projectsadmin->contains($projectrole)) $projectsadmin->add($projectrole);
            }
        }

        // Récupération des projects par group
        foreach($groups as $group) {
            $qb = $this->createQueryBuilder("project");
            $qb ->where(":group MEMBER OF project.groups")
                ->andWhere("project.user != :user or project.user is null")
                ->setParameter('user',$user)
                ->setParameter("group",$group->getGroup());
            
            $projectsgroups=$qb->getQuery()->getResult();
            foreach($projectsgroups as $projectgroup) {
                if(!$projectsadmin->contains($projectgroup)) $projectsadmin->add($projectgroup);
            }
        }

        // Permission sur les projects
        foreach($projectsadmin as $projectadmin) {
            $projectadmin->setCanupdate($this->getInmanager($user,$projectadmin));
            $projectadmin->setCanadd($this->getInwriter($user,$projectadmin));
        }     
    }

    public function getPermission($user,$project,&$cansee,&$canupdate,&$canadd) {
        // si project de l'utilisateur
        if($project->getUser()==$user&&!is_null($user)) {
            $cansee=true;
            $canupdate=true;
            $canadd=true;
        }
        else {
            $canupdate=false;
            $cansee=false;
            $canadd=false;

            // Profilage
            $roles=($user?$user->getRoles():["ROLE_ANONYME"]);
            $groups=($user?$user->getGroups():[]);

            // Le project est-il dans les projects associés au role de l'utilisateur ?
            foreach($roles as $role) {
                $qb = $this->createQueryBuilder("project");
                $qb ->where($qb->expr()->like('project.roles', $qb->expr()->literal("%$role%")))
                    ->andWhere("project.id=:id")
                    ->andWhere("project.user is null")
                    ->setParameter("id",$project->getId());
                $inprojectrole=$qb->getQuery()->getResult();
                if($inprojectrole) $cansee=true;
            }   
            

            // Le project est-il dans les projects associés aux groupes de l'utilisateur ?
            foreach($groups as $group) {
                $qb = $this->createQueryBuilder("project");
                $qb ->where(":group MEMBER OF project.groups")
                    ->andWhere("project.id=:id")
                    ->setParameter("id",$project->getId())
                    ->setParameter("group",$group->getGroup());
                
                $inprojectgroup=$qb->getQuery()->getResult();
                if($inprojectgroup)  {
                    $cansee=true;

                    // Est-il manager du groupe
                    if($group->getGroup()->getFgcanshare()) {
                        if($group->getRolegroup()>=90) $canupdate=true;
                        if($group->getRolegroup()>=0) $canadd=true;
                    }
                }
            } 

            // utilisateur a-t-il la permission d'écriture
            $canadd=$this->getInwriter($user,$project);
            
        }
    }

    public function getInwriter($user,$project) {
        $can=false;

        if($user) {
            // Peut ecrire ceux qui sont déclaré comme écrivain
            $qb = $this->createQueryBuilder("project");
            $qb ->andWhere("project.id=:id")
                ->andwhere(':user MEMBER OF project.writers')

                ->from('App\Entity\User','user')
                ->andwhere("user=:user")
                
                ->from('App\Entity\UserGroup','usergroup')
                ->andwhere('usergroup.group MEMBER OF project.groups')
                ->andwhere('usergroup.user=:user')

                ->setParameter("id",$project->getId())
                ->setparameter('user',$user);            

            $inprojectwriters=$qb->getQuery()->getResult();
            if($inprojectwriters) $can=true;

            // Peut ecrire ceux qui sont manager du groupe auquel est rattaché le project
            $qb = $this->createQueryBuilder("project");
            $qb ->andWhere("project.id=:id")
                ->from('App\Entity\User','user')
                ->andwhere("user=:user")

                ->from('App\Entity\UserGroup','usergroup')
                ->andwhere('usergroup.group MEMBER OF project.groups')
                ->andwhere('usergroup.user=:user')
                ->andwhere('usergroup.rolegroup>=:role')

                ->from('App\Entity\Group','groupe')
                ->andwhere('groupe=usergroup.group')
                ->andwhere('groupe.fgcanshare=:flag')

                ->setParameter("id",$project->getId())
                ->setparameter('user',$user)
                ->setparameter('flag',true)
                ->setparameter('role',0);


            $inprojectwriters=$qb->getQuery()->getResult();
            if($inprojectwriters) $can=true;            
        }
        
        return $can;
    }

    public function getInmanager($user,$project) {
        $can=false;

        if($user) {
            // Peut ecrire ceux qui sont manager du groupe auquel est rattaché le project
            $qb = $this->createQueryBuilder("project");
            $qb ->andWhere("project.id=:id")
                ->from('App\Entity\User','user')
                ->andwhere("user=:user")

                ->from('App\Entity\UserGroup','usergroup')
                ->andwhere('usergroup.group MEMBER OF project.groups')
                ->andwhere('usergroup.user=user')
                ->andwhere('usergroup.rolegroup>=:role')

                ->from('App\Entity\Group','groupe')
                ->andwhere('groupe=usergroup.group')
                ->andwhere('groupe.fgcanshare=:flag')

                ->setParameter("id",$project->getId())
                ->setParameter("role",90)
                ->setparameter('user',$user)
                ->setparameter('flag',true);


            $inblogwriters=$qb->getQuery()->getResult();
            
            if($inblogwriters) $can=true;     
        }
        
        return $can;
    }   
    
    public function getInvalideur($user,$project) {
        $can=false;

        if($user) {
            // Peut ecrire ceux qui sont manager du groupe auquel est rattaché le project
            $qb = $this->createQueryBuilder("project");
            $qb ->andWhere("project.id=:id")
                ->from('App\Entity\User','user')
                ->andwhere("user=:user")

                ->from('App\Entity\UserGroup','usergroup')
                ->andwhere('usergroup.group MEMBER OF project.groups')
                ->andwhere('usergroup.user=user')
                ->andwhere('usergroup.rolegroup>=:role')

                ->from('App\Entity\Group','groupe')
                ->andwhere('groupe=usergroup.group')
                ->andwhere('groupe.fgcanshare=:flag')

                ->setParameter("id",$project->getId())
                ->setParameter("role",50)
                ->setparameter('user',$user)
                ->setparameter('flag',true);


            $inblogwriters=$qb->getQuery()->getResult();
            
            if($inblogwriters) $can=true;     
        }
        
        return $can;
    } 
}
