<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Serializer;
use Doctrine\Persistence\ManagerRegistry;
use Ramsey\Uuid\Uuid;

use App\Entity\User;
use App\Entity\Group;
use App\Entity\Bookmark;
use App\Entity\Edispatcher;

class EdispatcherController extends AbstractController
{

   public function applications(ManagerRegistry $em) {
        $itemcategorys = $em->getRepository('App\Entity\Itemcategory')->findBy([], ['rowOrder' => 'asc']);
        foreach($itemcategorys as $itemcategory) {
            $items = $itemcategory->getItems();

            foreach($items as $item) {
                $output = [];
                $output["id"] = $item->getId();
                $output["name"] = $item->getTitle();
                $output["libelle"] = $item->getSubtitle();
                $output["icon"] = $item->getIcon()?$item->getIcon()->getLabel():"default";
                $output["url"] = $item->getUrl();
                $output["profils"] = [];

                foreach($item->getGroups() as $group) {
                    $output["profils"]["groupes"][] = "NINEGATE|".$group->getLabel();
                }
                foreach($item->getRoles() as $role) {
                    $output["profils"]["roles"][] = "NINEGATE|".$role;
                }

                if ($item->getSsoitem()!="") $output["profils"]["SSOITEM"] = $item->getSsoitem();
		        
                $reponse[$item->getTitle()] = $output;
            }
        }
        
        return new Response(json_encode($reponse), Response::HTTP_OK);
    }

    public function checkuser(Request $request, ManagerRegistry $em) {
        $id = $request->query->get('id',false);
        if ($id) {
            $user=$em->getRepository('App\Entity\User')->findOneBy(["username"=>$id]);
            if (!$user) {
                $output["error"]="id=".$id." : user not found";
                return new Response(json_encode($output), 400);
            }

            $output["username"] = $user->getUsername();
            $output["firstname"] = $user->getFirstname();
            $output["lastname"] = $user->getLastname();
            $output["email"] = $user->getEmail();
            $output["role"] = $user->getRole();
            
            foreach($user->getGroups() as $group) {
                $output["groupes"][] = $group->getGroup()->getLabel();
            }
        }
        else {
            $output["error"]="id needed";
            return new Response(json_encode($output), 404);
        }

        return new Response(json_encode($output), Response::HTTP_OK);
    }


    public function test(Request $request, ManagerRegistry $em) {
        $Datasource = $em->getRepository('App\Entity\Edispatcher')->findAll();
        $id = $request->query->get('id',false);
        if ($id) {
            $user=$em->getRepository('App\Entity\User')->findOneBy(["username"=>$id]);
            if (!$user) {
                $output["error"]="id=".$id." : user not found";
                return new Response(json_encode($output), 400);
            }

            $groups = array();
            foreach($user->getGroups() as $usergroup) {
                $tmp = $usergroup->getGroup()->getLabel();
                array_push($groups,$tmp);
            }
            $groups = implode("|",$groups);
        }
        else {
            $groups = "syntaxe: /edispatcher/test?id={username} - pour afficher une liste des groupes d'un username arbitraire (pas celui en session)";
        }
        
        // Init Client CAS
        \phpCAS::setDebug(false);
        @\phpCAS::client(CAS_VERSION_2_0, $this->getParameter('cas_host'), intval($this->getParameter('cas_port')), is_null($this->getParameter('cas_path')) ? '' : $this->getParameter('cas_path'), $this->getHost($request), false);
        \phpCAS::setNoCasServerValidation();

        // Authentification
        \phpCAS::forceAuthentication();

        // Récupération UID
        $username = \phpCAS::getUser();
        $attributes = \phpCAS::getAttributes();
        if(isset($attributes[$this->getParameter('user_attr_cas_username')]))
            $login = $attributes[$this->getParameter('user_attr_cas_username')];
        
        $user=$em->getRepository('App\Entity\User')->findOneBy(["username"=>$login]);
        if(!$user) {
            $output["error"]="user does not exist";
            return new Response(json_encode($output), 400);
	    }
        
        $roles=($user?$user->getRoles():["ROLE_ANONYME"]);
        if (in_array("ROLE_ADMIN",$roles)) {
        	return $this->render('Edispatcher\test.html.twig',[
	            'useheader'         => true,
	            'usemenu'           => false,
	            'usesidebar'        => false,
	            'attributes'        => $attributes,
	            'groups'            => $groups,
	            'username'          => $username,
	            'Datasource'        => $Datasource,
	        ]);
        }
        else {
            $output["error"]="access not granted";
            return new Response(json_encode($output), 403);
        } 
    }

    public function desktopitem(Request $request, ManagerRegistry $em) {
        $id = $request->query->get('id','null');

        // Récupération Attribut
        // acces base pour recuperer profil et groupe pour le user
        $Datasource = $em->getRepository('App\Entity\Edispatcher')->findOneBy(["iddatasource"=>$id]);
        if (!$Datasource) {
            $output["error"]="no Datasource session found for id = $id";
            return new Response(json_encode($output), 400);
        }
        $login = $Datasource->getUsername();
        $profil = $Datasource->getProfil();

   		// Récupérer l'utilisateur
		$user=$em->getRepository('App\Entity\User')->findOneBy(["username"=>$login]);
		if(!$user) {
			$output["error"]="user not exist";
			return new Response(json_encode($output), 400);
		}

        $groups = array();
        foreach($user->getGroups() as $usergroup) {
            $tmp = $usergroup->getGroup()->getLabel();
            array_push($groups,$tmp);
        }

        $groupes=implode("|",$groups);

        $listessoitems = $Datasource->getSsoitems();
        $ssoitems=explode("|",$listessoitems);


		// Format de sortie
		$output["bookmarks"]        = [];
		$output["items"]            = [];
		$output["itemcategorys"]    = [];

		$bookmarks=null;
		$items=null;
		$itemcategorys=null;
		$weburl="//".$this->getParameter("weburl")."/".$this->getParameter("alias");

        $em->getRepository("App\Entity\Item")->getUserItems($user,$bookmarks,$items,$itemcategorys,null,$ssoitems,3);

        $itemsperso = false;
		if($bookmarks) {
			foreach($bookmarks as $bookmark) {
				$tmp=[];
				$tmp["id"]          = $bookmark->getId();
				$tmp["title"]       = $bookmark->getTitle();
				$tmp["subtitle"]    = $bookmark->getSubtitle();
				$tmp["url"]         = $bookmark->getUrl();
				$tmp["target"]      = $bookmark->getTarget();
				$tmp["order"]       = 0;
				$tmp["icon"]        = $weburl.($bookmark->getIcon()?$bookmark->getIcon()->getLabel():"uploads/icon/icon_pin.png");
				$tmp["color"]       = ($bookmark->getColor()?$bookmark->getColor():$this->get('session')->get('color')["main"]);
				$tmp["essential"]   = false;
                if ($bookmark->getItem())
				    $tmp["category"]    = $bookmark->getItem()->getItemcategory()->getId();
                else {
                    $tmp["category"] = -999;
                    $itemsperso = true;
                }
				$tmp["badge_url"]   = "";
				$tmp["badge_type"]  = "";
				$tmp["badge_message"]   = "";
				$tmp["mode"]        = false;

				if ($tmp["category"] != -999) array_push($output["bookmarks"],$tmp);
				array_push($output["items"],$tmp);
			}
        }
        
        $arrayitems = array();
		if($items) {
			foreach($items as $item) {
				$tmp=[];
				$tmp["id"]          = $item->getId();
				$tmp["title"]       = $item->getTitle();
				$tmp["subtitle"]    = $item->getSubtitle();
				$tmp["url"]         = $item->getUrl();
				$tmp["target"]      = $item->getTarget();
				$tmp["order"]       = $item->getRoworder();
				$tmp["color"]       = ($item->getColor()?$item->getColor():$this->get('session')->get('color')["main"]);
				$tmp["icon"]        = $weburl.($item->getIcon()?$item->getIcon()->getLabel():"uploads/icon/icon_pin.png");
				$tmp["essential"]   = $item->getEssential();
				$tmp["category"]    = $item->getItemcategory()->getId();
				$tmp["badge_url"]   = "";
				$tmp["badge_type"]  = "";
				$tmp["badge_message"] = "";
				$tmp["mode"]        = false;

				array_push($arrayitems,$tmp);
			}
		}

        sort($arrayitems);
        foreach ($arrayitems as $elem) {
            if (!in_array($elem,$output["items"])) array_push($output["items"],$elem);
        }
        $arrayitemcats = array();
		if($itemcategorys) {
			foreach($itemcategorys as $itemcategory) {
				$tmp=[];
				$tmp["id"]          = $itemcategory->getId();
				$tmp["title"]       = $itemcategory->getLabel();
				$tmp["order"]       = $itemcategory->getRoworder();
				$tmp["color"]       = ($itemcategory->getColor()?$itemcategory->getColor():$this->get('session')->get('color')["main"]);
				array_push($arrayitemcats,$tmp);
			}
		}
        sort($arrayitemcats);
        foreach ($arrayitemcats as $elem) {
            if (!in_array($elem,$output["itemcategorys"])) array_push($output["itemcategorys"],$elem);
        }
		//
		// xdesktop2ninegate 2020
		//

		// Gestion des infos du profil ==============
        $rne = $user->getSiren();

		$arr=array();
        $arr["profil"]=$profil;
		$arr["rne"]=$rne;
        $arr["groupes"]=$groupes;
		$user_infos=json_encode($arr);

		// L'ensemble des favoris qui correspond à l'utilisateur
		$tbfav=array();
		foreach($output["bookmarks"] as $bookmark) {
			$tmp=array('url'=>$bookmark['url'],'libelle'=>$bookmark['title'],'icon'=>$bookmark['icon']);
			array_push($tbfav,$tmp);
		}

		$favoris=json_encode($tbfav);

        // Nom des categories
        $tbcat = $output["itemcategorys"];
		$cat=array();
		foreach($tbcat as $item)
		{
		   $cat[$item['id']] = $item['title'];
		}

        $tbitem = $output["items"];
        // Construction de la chaine xml
        $carriage_return   = array("\r\n", "\n", "\r");
        $ret_str="<main>";
        $ret_str=$ret_str."<buttondatas>";
        foreach($tbitem as $item) {
            $ret_str=$ret_str."<buttondata>";
            $ret_str=$ret_str."<nom>".str_replace("&"," ",($item['title']))."</nom>";
            $ret_str=$ret_str."<icon>".htmlentities(($item['icon']))."</icon>";
            $ret_str=$ret_str."<libelle>".str_replace("&"," ",($item['subtitle']))."</libelle>";
            $ret_str=$ret_str."<url>".htmlentities(($item['url']))."</url>";
            if ( $item['category'] != -999 ) {
                $ret_str=$ret_str."<categoriename>".($cat[$item['category']])."</categoriename>";
            } else $ret_str=$ret_str."<categoriename>Mes Ressources</categoriename>";
            $ret_str=$ret_str."<categorieid>".$item['category']."</categorieid>";
            $ret_str=$ret_str."<infos_url>".htmlentities($item['badge_url'])."</infos_url>";
            $ret_str=$ret_str."<infos_type>".$item['badge_type']."</infos_type>";

            # ref: #5629 et #4261
            if ($item['mode']) {
                $ret_str=$ret_str."<external>true</external>";
            }

            $ret_str=$ret_str."<infos_message>".str_replace($carriage_return,"<br/>",htmlentities($item['badge_message']))."</infos_message>";
            $ret_str=$ret_str."</buttondata>";
        }
        $ret_str=$ret_str."</buttondatas>";

        // Description
        $ret_str=$ret_str."<description>";
        $ret_str=$ret_str."<services_url>mxServices</services_url>";
        $ret_str=$ret_str."</description>";

        // Categories
        $ret_str=$ret_str."<categories>";
        foreach ($tbcat as $categorie) {
            $ret_str=$ret_str."<categorie>";
            $ret_str=$ret_str."<nom>".$categorie['title']."</nom>";
            if (isset($categorie['color'])) $ret_str=$ret_str."<couleur>".$categorie['color']."</couleur>";
            $ret_str=$ret_str."<indice>".$categorie['order']."</indice>";
            $ret_str=$ret_str."<icone></icone>";
            $ret_str=$ret_str."</categorie>";
        }
        if ($itemsperso) {
            $ret_str=$ret_str."<categorie>";
            $ret_str=$ret_str."<nom>Mes Ressources</nom>";
            $ret_str=$ret_str."<indice>-1</indice>";
            $ret_str=$ret_str."<icone>fa-star</icone>";
            $ret_str=$ret_str."</categorie>";
        }

        $ret_str=$ret_str."</categories>";
        $ret_str=$ret_str."</main>";

        if (isset($_GET["callback"])) {postData($ret_str,$message,$favoris,$user_infos);die();}

        $message="";

        // Si js
        if (isset($_GET["js"])) {
            $id=$_GET["id"];
            header("Content-type: text/javascript");

            $data=json_encode(array("xml"=>(htmlentities($ret_str,ENT_QUOTES,"UTF-8")),
                                    "favoris"=>(htmlentities($favoris,ENT_QUOTES,"UTF-8")),
                                    "userinfos"=>(htmlentities(str_replace("'",'"',$user_infos),ENT_QUOTES,"UTF-8")),
                                    "id"=>$id/*,
                                    "referer"=>(isset($_SERVER['HTTPS']) ? "https" : "http") . "://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"*/
                            ));
            ob_start();
            echo <<<EOL
/* DATA_FOR_MXDESKTOP: Ne pas supprimer cette ligne */
    var username='$login';
    var source=MX.getSource('$id');
    if (!source) {
        console.log("Source $id introuvable");
    } else {
        source.setData('$data');
    }
EOL
    ;
            $sortie= ob_get_clean();
            $reponse = new Response();
            $reponse->setContent($sortie);
            $reponse->headers->set('Content-Type', 'text/javascript');
            return $reponse;
        }

        ob_start();
        echo $ret_str;
        echo "\n";
        echo "MSG=$message";
        echo "\n";
        echo "FAV=$favoris";
        echo "\n";
        echo "UI=$user_infos";
        $sortie= ob_get_clean();
        $reponse = new Response();
        $reponse->setContent($sortie);
        $reponse->headers->set('Content-Type', 'text/html');
        return $reponse;
    }

    public function message($idalert = null,$action = null,$access="config", Request $request, ManagerRegistry $em) {
        $id = $request->query->get('id',null);
        $token = $request->request->get('token',null);
        $data = $request->request->get('data',null);
        if($data) $token=$data['token'];
        $api = $request->query->get('api','');
        // Tester présence des parametres
        if ((is_null($id)) and (is_null($token))) {
            $output["error"]="missing parameter : id / token";
            return new Response(json_encode($output), 400);
        }

        // Récupération Attribut
        // acces base pour recuperer profil et groupe pour le user
        if($id) $Datasource = $em->getRepository('App\Entity\Edispatcher')->findOneBy(["iddatasource"=>$id]);
        else if($token) $Datasource = $em->getRepository('App\Entity\Edispatcher')->findOneBy(["token"=>$token]);
        if (!$Datasource) {
            $output["error"]="no Datasource session found for id = $id / token = $token";
            return new Response(json_encode($output), 400);
        }
        $username = $Datasource->getUsername();

        // Gestion des infos du profil ==============
        $output = [];

        // Récupérer l'utilisateur
        $user=$em->getRepository('App\Entity\User')->findOneBy(["username"=>$username]);
        if(!$user) {
            $output["error"]="user not exist";
            return new Response(json_encode($output), 400);
        }

        $weburl="//".$this->getParameter("weburl")."/".$this->getParameter("alias");
        $serializer = new Serializer(array(new DateTimeNormalizer()));

        if ($action == null) {
            // /!\ ->getUserAlerts from eoledev repository paquet dev1.0+3-100 (ssoitems)
            $listessoitems = $Datasource->getSsoitems();
            $ssoitems=explode("|",$listessoitems);
            $alerts=$em->getRepository("App\Entity\Alert")->getUserAlerts($user,null,null,$ssoitems);
            $messages = [];

            foreach($alerts as $alert) {
                $tmp=[];
                $tmp["id"]          = $alert->getId();
                $bgcolor = ($alert->getAlertcategory()->getColor()?$alert->getAlertcategory()->getColor():$this->get('session')->get('color')["main"]);
                $iconeurl = $weburl.($alert->getAlertcategory()->getIcon()?$alert->getAlertcategory()->getIcon()->getLabel():"uploads/icon/icon_pin.png");
                $compteur=0;
                $urls=[];
                foreach($alert->getItems() as $item) {
                    $urls[] = $item->getUrl();
                    $compteur++;
                }
                $tmp["url"]  = implode("|",$urls);
                switch ($alert->getAlertcategory()->getLabel()) {
                    case "sans categorie": $flag="none"; break;
                    case "Rappel": $flag="rappel"; break;
                    case "Attention/Important": $flag="attention"; break;
                    case "Message": $flag="mail"; break;
                    default: $flag=""; break;
                }
                $categorielabel="";
                if ($compteur==0) {
                        if ($flag=="") {
                            $categorielabel="<div style='float:left;width: 102.5%;padding: 4px;padding-left: 4px;color:white;background-color: #$bgcolor;position:relative;top: -16px;left: -11px;'><img src='$iconeurl' width='24em'>&nbsp;".$alert->getAlertcategory()->getLabel()."</div></br>";
                            $tmp["message"]     = "$categorielabel<h4>".$alert->getTitle()."</h4>".$this->replaceContent($alert->getContent());
                        } else $tmp["message"]     = "<h4>".$alert->getTitle()."</h4>".$this->replaceContent($alert->getContent());
                }
                else
                {
                        if ($flag=="") {
                            $categorielabel="<img src='$iconeurl' width='16em' ><span style='font-weight: bold'> ".$alert->getAlertcategory()->getLabel()."</span> : ";
                            $tmp["message"]     = $categorielabel.$alert->getTitle()."".$this->replaceContent($alert->getContent());
                        } else $tmp["message"]     = $alert->getTitle()."</br>".$this->replaceContent($alert->getContent());
                }
                $tmp["filtre"]      = "aucun";
                $tmp["valeur"]      = "[]";
                $tmp["flag"]        = $flag;
                $tmp["closeable"]   = ($alert->getFghideable()?"true":"false");
                $tmp["requestable"] = "false";
                $tmp["display_mode"]= "postit";
                $tmp["responses"]   = "[]";
                $tmp["start"]       = $serializer->normalize($alert->getPublishedat(),null,array(DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s'));
                $tmp["stop"]        = $serializer->normalize($alert->getUnpublishedat(),null,array(DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s'));
                $tmp["updated"]     = $serializer->normalize($alert->getPublishedat(),null,array(DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s'));
                $tmp["user_responses"] = "[]";
                array_push($messages,$tmp);
            }

            $data = json_encode([
                'messages'        => $messages,
                'admin' => false,
            ]);
            $datajs="var data=$data;
            $api('$id',data);";
            $reponse = new Response();
            $reponse->setContent($datajs);
            $reponse->headers->set('Content-Type', 'text/javascript');
        }
        else if ($action=="never") {
            /*
             * ACTION : BASCULER LA VISIBILITE DU MESSAGE : SI VISIBLE, LE CACHER ET INVERSEMENT
             */
            // Tester présence des parametres
            if(is_null($idalert)||is_null($action)) {
                $output["error"]="missing parameter : idalert - action";
                return new Response(json_encode($output), 400);
            }

            // Tester l'existence de l'alert
            $alert=$em->getRepository('App\Entity\Alert')->find($idalert);
            if(!$alert) {
                $output["error"]="alert not exist";
                return new Response(json_encode($output), 400);
            }

            // construction de la réponse
            $tmp=[];
            $tmp["id"]          = $alert->getId();
            $bgcolor = ($alert->getAlertcategory()->getColor()?$alert->getAlertcategory()->getColor():$this->get('session')->get('color')["main"]);
            $iconeurl = $weburl.($alert->getAlertcategory()->getIcon()?$alert->getAlertcategory()->getIcon()->getLabel():"uploads/icon/icon_pin.png");
            $tmp["message"]     = "<div width=100% style='background-color:#$bgcolor;color:white;padding:12px'><h4><img src='$iconeurl' width='30em' ><span style='font-weight: bold'> ".$alert->getAlertcategory()->getLabel()."</span> : <small style='color:white'>".$alert->getTitle()."</small></h4>".$this->replaceContent($alert->getContent())."</div>";
            $tmp["filtre"]      = "aucun";
            $tmp["valeur"]      = "[]";
            $tmp["flag"]        = "";
            $tmp["closeable"]   = ($alert->getFghideable()?"true":"false");
            $tmp["requestable"] = "false";
            $tmp["display_mode"]= "postit";
            $tmp["responses"]   = "[]";
            $tmp["start"]       = $serializer->normalize($alert->getPublishedat(),null,array(DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s'));
            $tmp["stop"]        = $serializer->normalize($alert->getUnpublishedat(),null,array(DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s'));
            $tmp["updated"]     = $serializer->normalize($alert->getPublishedat(),null,array(DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s'));
            $tmp["user_responses"] = "[]";

            // Tester que l'alert est masquable
            if(!$alert->getFghideable()) {
                $output["error"]="alert not hideable";
                return new Response(json_encode($output), 400);
            }

            // Basculer l'état de visibilité de l'alert
            if($alert->getReaders()->contains($user)) $alert->removeReader($user);
            else $alert->addReader($user);

            $em->getManager()->persist($alert);
            $em->getManager()->flush();

            $reponse=new Response(json_encode($tmp), 200);
            $reponse->headers->set('Access-Control-Allow-Origin', '*');
            return $reponse;
        }
        else if ($action=="reset") {
            /*
             * ACTION : RESTAURER LE MESSAGE
             */
            // Tester présence des parametres
            if(is_null($idalert)||is_null($action)) {
                $output["error"]="missing parameter : idalert - action";
                return new Response(json_encode($output), 400);
            }

            // Tester l'existence de l'alert
            $alert=$em->getRepository('App\Entity\Alert')->find($idalert);
            if(!$alert) {
                $output["error"]="alert not exist";
                return new Response(json_encode($output), 400);
            }

            // construction de la réponse
            $tmp=[];
            $tmp["id"]          = $alert->getId();
            $bgcolor = ($alert->getAlertcategory()->getColor()?$alert->getAlertcategory()->getColor():$this->get('session')->get('color')["main"]);
            $iconeurl = $weburl.($alert->getAlertcategory()->getIcon()?$alert->getAlertcategory()->getIcon()->getLabel():"uploads/icon/icon_pin.png");
            $tmp["message"]     = "<div width=100% style='background-color:#$bgcolor;color:white;padding:12px'><h4><img src='$iconeurl' width='30em' ><span style='font-weight: bold'> ".$alert->getAlertcategory()->getLabel()."</span> : <small style='color:white'>".$alert->getTitle()."</small></h4>".$this->replaceContent($alert->getContent())."</div>";
            $tmp["filtre"]      = "aucun";
            $tmp["valeur"]      = "[]";
            $tmp["flag"]        = "";
            $tmp["closeable"]   = ($alert->getFghideable()?"true":"false");
            $tmp["requestable"] = "false";
            $tmp["display_mode"]= "postit";
            $tmp["responses"]   = "[]";
            $tmp["start"]       = $serializer->normalize($alert->getPublishedat(),null,array(DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s'));
            $tmp["stop"]        = $serializer->normalize($alert->getUnpublishedat(),null,array(DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s'));
            $tmp["updated"]     = $serializer->normalize($alert->getPublishedat(),null,array(DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s'));
            $tmp["user_responses"] = "[]";

            // Tester que l'alert est masquable
            if(!$alert->getFghideable()) {
                $output["error"]="alert not hideable";
                return new Response(json_encode($output), 400);
            }

            // Restaurer l'alert
            if($alert->getReaders()->contains($user)) {
                $alert->removeReader($user);
                $em->getManager()->persist($alert);
                $em->getManager()->flush();
            }

            $reponse=new Response(json_encode($tmp), 200);
            $reponse->headers->set('Access-Control-Allow-Origin', '*');
            return $reponse;

        } else {
            dump("action = $action sur idmsg = $idmsg");
            die;
        }
        return $reponse;
    }

    public function hello() {
        $reponse = new Response('ninegate', Response::HTTP_OK);
	    $reponse->headers->set('Access-Control-Allow-Origin', '*');
        return $reponse;
    }

    public function me($access="config",Request $request, ManagerRegistry $em) {
        $token = $request->query->get('token',false);

        // Récupération Attribut
        // acces base pour recuperer profil et groupe pour le user
        if ($token) {
            $Datasource = $em->getRepository('App\Entity\Edispatcher')->findOneBy(["token"=>$token]);
            if (!$Datasource) {
                $output["error"]="no Datasource session found for token = $token";
                return new Response(json_encode($output), 400);
            }
            $username = $Datasource->getUsername();
        } else {
            $output["error"]="no token provided - Abort";
            return new Response(json_encode($output), 400);
        }

        $output = [];

        // Récupérer l'utilisateur
        $user=$em->getRepository('App\Entity\User')->findOneBy(["username"=>$username]);
        if(!$user) {
            $output["error"]="user not exist";
            return new Response(json_encode($output), 400);
        }
        $roles=($user?$user->getRoles():["ROLE_ANONYME"]);
        if (in_array("ROLE_MODO",$roles)) {
            $permmod=$em->getRepository("App\Entity\PermModo")->findOneBy(["route"=>"app_portal_config_alert","permmodoprofil"=>$user->getPermmodoprofil()]);
            $adminpostit=$permmod?$permmod->getVisible():false;
        } else $adminpostit=in_array("ROLE_ADMIN",$roles);

        // Profilage
        $username = $user->getFirstName()." ".$user->getLastName();
        $reponse = new Response();
        $reponse->setContent(json_encode([
            'display_name'        => $username,
            'admin_postit'        => $adminpostit,
        ]));

        $reponse->headers->set('Content-Type', 'text/html');
        $reponse->headers->set('Access-Control-Allow-Origin', '*');
        return $reponse;
    }

    public function session($id="",$access="config",Request $request, ManagerRegistry $em) {
        // mode_auth
        $mode_auth=$this->getParameter("mode_auth");
        if($mode_auth!="CAS") {
            $output["error"]="Le bundle Edispatcher ne fonctionne qu'en mode mode_auth=CAS";
            return new Response(json_encode($output), 400);
        }

        // Init Client CAS
        \phpCAS::setDebug(false);
        @\phpCAS::client(CAS_VERSION_2_0, $this->getParameter('cas_host'), intval($this->getParameter('cas_port')), is_null($this->getParameter('cas_path')) ? '' : $this->getParameter('cas_path'), $this->getHost($request), false);
        \phpCAS::setNoCasServerValidation();

        // Authentification
        \phpCAS::forceAuthentication();

        // Récupération UID
        $username = \phpCAS::getUser();
        $attributes = \phpCAS::getAttributes();
        $profil = $attributes["ENTPersonProfils"];

        // -- autocreate

        // Rechercher l'utilisateur
        if(isset($attributes[$this->getParameter('user_attr_cas_username')]))
            $username = $attributes[$this->getParameter('user_attr_cas_username')];

        if(isset($attributes[$this->getParameter('user_attr_cas_mail')]))
            $email = $attributes[$this->getParameter('user_attr_cas_mail')];

        if(isset($attributes[$this->getParameter('user_attr_cas_lastname')]))
            $lastname = $attributes[$this->getParameter('user_attr_cas_lastname')];

        if(isset($attributes[$this->getParameter('user_attr_cas_firstname')]))
            $firstname = $attributes[$this->getParameter('user_attr_cas_firstname')];
        $user = $em->getRepository('App\Entity\User')->findOneBy(array("username"=>$username));

        if (!$user) {
                $user = new User();
                // On calcule le niveau01 de l'utilisateur
                $niveau01=$em->getRepository('App\Entity\Niveau01')->calculateNiveau01($attributes);
                if(!$niveau01)
                    throw $this->createNotFoundException('Permission denied. No Organisation Niveau 01 match');
                $user->setUsername($username);
                $user->setEmail($email);
                $user->setLastname($lastname);
                $user->setFirstname($firstname);
                $user->setPassword("CASPWD-".$username);
                $user->setSalt("CASPWD-".$username);
                $user->setApikey(Uuid::uuid4());

                $user->setNiveau01($niveau01);
                $user->setSiren($niveau01->getSiren());
                $user->setSiret("");
                $user->setAvatar("noavatar.png");
                $user->setVisible(true);
                $user->setAuthlevel("simple");
                $user->setBelongingpopulation("agent");
                $user->setRole("ROLE_USER");

                if(in_array($username,$this->getParameter("ldap_usersadmin")))
                    $user->setRole("ROLE_ADMIN");
                $em->getManager()->persist($user);
                $em->getManager()->flush();

                // Génération auto des groupes
                $this->submitGroup($em,$attributes);
                // On calcule les groupes de l'utilisateur
                $user=$em->getRepository('App\Entity\Group')->calculateGroup($user,$attributes);
        }

        //-- fin de l'auto create --

        // groupes depuis ninegate
        $roles=($user?$user->getRoles():["ROLE_ANONYME"]);
        $adminpostit=(in_array("ROLE_MODO",$roles));
        $groups = array();
        foreach($user->getGroups() as $usergroup) {
          $tmp = $usergroup->getGroup()->getLabel();
          array_push($groups,$tmp);
        }
        $groupes=implode("|",$groups);

        if($this->getParameter('ssosynchroitem')) {
            $ssoitems=implode("|",$attributes[$this->GetParameter("user_attr_cas_item")]);
        } else $ssoitems = "";

        $request = $this->container->get('request_stack')->getCurrentRequest();
        $api = $request->query->get('api','null');
        $id = $request->query->get('id','xxxxx-xxxxx-xxxx');

        // profil et groupes fournis par SSO => on les update dans l'entité Datasource
        // en attendant que les infos soient dispos dans le modele User de ninegate
        $Datasource = $em->getRepository('App\Entity\Edispatcher')->findOneBy(["username"=>$username]);
        if(!$Datasource) {
            $Datasource = new Edispatcher();
            $Datasource->setUsername($username);
            $token = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyz'),1,16);
            $Datasource->setToken($token);
            $Datasource->setHorodatage(date('YmdHi'));
        } else $token = $Datasource->getToken();
        $Datasource->setProfil($profil);
        $Datasource->setGroupes($groupes);
        $Datasource->setIddatasource($id);
        $Datasource->setSsoitems($ssoitems);

        // persistance du token pour 24h (1j)
        $horodatage=$Datasource->getHorodatage();
        $maintenant=date('YmdHi');
        $delta=($maintenant)-($horodatage);
        if ($delta > 10000) {
            $token = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyz'),1,16);
            $Datasource->setToken($token);
            $Datasource->setHorodatage(date('YmdHi'));
        }

        $em->getManager()->persist($Datasource);
        $em->getManager()->flush();

        $data = json_encode([
            'token'        => $token,
            'adminPostit'  => $adminpostit,
        ]);
        // Profilage
        $reponse = new Response();
        if ($api!="null") {
            $datajs="var data=$data;
            $api('$id',data);";
            $reponse->setContent($datajs);
            $reponse->headers->set('Content-Type', 'text/javascript');
        }
        else {
            $reponse->setContent($data);
            $reponse->headers->set('Content-Type', 'text/html');
        }
        //$reponse->headers->set('Access-Control-Allow-Origin', '*');
        return $reponse;
    }

    // /edispatcher/api/mxServices
    //
    // Ajout d'un item ninegate existant comme bookmark d'un utilisateur
    // POST
    // token = Datasource user token, permettant d'établir le lien avec l'uid de l'utilisateur
    // GET
    // id = id interne de l'item sur lequel on souhaite ajouter/supprimer un bookmark
    // libelle = libelle de la ressource
    // icon = icone de la ressource
    // favurl = url icone escapée
    // nom = nom ou id
    // categorie = categorie de la ressource
    // callback = url du call back à retourner
    // action = BOOKMARK_ADD | BOOKMARK_DEL
    // callbackid = listeDesApplications/idinterne
    public function mxServices(Request $request, ManagerRegistry $em) {

        $token = $request->query->get('token',null);
        $id = $request->query->get('id',null);
        $libelle =$request->query->get('libelle',null);
        $icon =$request->query->get('icon',null);
        $favurl = rtrim($request->query->get('favurl',null),"?");
        // urldecode(stripslashes(
        $nom =$request->query->get('nom',null);
        $categorie =$request->query->get('categorie',null);
        $callback =$request->query->get('callback',null);
        $action =$request->query->get('action',null);
        $callbackid =$request->query->get('callbackid',null);

        ob_start();
        //var_dump($request->request);
        var_dump($request->query);
        $debug = ob_get_clean();
        //$debug=json_encode($request->query);

	//return new Response(json_encode($output), 400);
        if(is_null($token)||is_null($libelle)||is_null($icon)||is_null($favurl)||is_null($nom)||is_null($categorie)||is_null($callback)||is_null($action)||is_null($callbackid)){
            $output["error"]="missing parameter : token - id - libelle - icon - favurl - nom - categorie - callback - action - callbackid";
        }

        // Récupération Attribut
        $Datasource = $em->getRepository('App\Entity\Edispatcher')->findOneBy(["token"=>$token]);
        if (!$Datasource) {
            $output["error"]="no Datasource session found for token = $token";
        }
        $login = $Datasource->getUsername();

        // Récupérer l'utilisateur
        $user=$em->getRepository('App\Entity\User')->findOneBy(["username"=>$login]);
        if(!$user) {
            $output["error"]="user does not exist";
        }

        // chercher l'item
        $item=$em->getRepository('App\Entity\Item')->findOneBy(["url"=>$favurl]);
        if(!$item) {
            $altitem=$em->getRepository('App\Entity\Item')->findOneBy(["url"=>$favurl."?gestion_edispatcher=locale"]);
            if(!$altitem) {
                $output["error"]="item with url=$favurl(?gestion_edispatcher=locale) not found";
            } else {
                $item = $altitem;
            }
        }

        $bookmark = $em->getRepository('App\Entity\Bookmark')->findOneBy(["user"=>$user,"item"=>$item]);
        $title="";
	    $subtitle="";
	    $message="";

	if (isset($output["error"])) {
		$message=$output["error"];
		$success=0;
	}
    else {
        $output="";
        if(!$bookmark) {
            if ($action=="BOOKMARK_ADD") {
                $bookmark = new Bookmark();
                $bookmark->setTitle($item->getTitle());
                $title=$item->getTitle();
                $bookmark->setSubtitle($item->getSubtitle());
                $subtitle=$item->getSubtitle();
                $bookmark->setUrl($item->getUrl());
                $bookmark->setIcon($item->getIcon());
                $bookmark->setColor($item->getColor());
                $bookmark->setTarget($item->getTarget());
                $bookmark->setItem($item);
                $bookmark->setUser($user);
                $em->getManager()->persist($bookmark);
                $em->getManager()->flush();

                $success=1;
                $message="$title : $subtitle a &eacute;t&eacute; ajout&eacute; &agrave; vos favoris";
            }
            else {
                $success=0;
                $message="item introuvable en favori mais action=DEL (retrait)";
            }
	    }
        else {
            if ($action=="BOOKMARK_DEL") {
                $em->getManager()->remove($bookmark);
                $em->getManager()->flush();
                $success=1;
                $message="item supprimé de vos favoris";
	        }
            else {
		        $success=0;
	            $message="item deja en favori mais action=ADD (ajout)";
            }
	    }
	}

    $output="<html><body>
<form id='form2submit' name='form2submit' method='POST' action='$callback'>
<input name='action'  id='action'  type='hidden' value='$action' />
<input name='message' id='message' type='hidden' value='$message' />
<input name='success' id='success' type='hidden' value='$success' />
<input name='id'      id='id'      type='hidden' value='$id' />
<input name='callbackid'      id='callbackid'      type='hidden' value='$callbackid' />
</form>
<script>
document.form2submit.submit();
</script>
</body></html>
";

        $reponse = new Response();
        $reponse->setContent($output);
        $reponse->headers->set('Content-Type', 'text/html');
        $reponse->headers->set('Access-Control-Allow-Origin', '*');
        return $reponse;
    }

    private function submitGroup($em, $attributes) {
        if(!$this->getParameter('ssosynchrogroup'))
            return null;

        $user_attr_cas_group=$this->getParameter('user_attr_cas_group');
        // Si l'utilisateur possège l'attribut groupe dans ses attributs
        if(array_key_exists($user_attr_cas_group,$attributes)) {
            if(!is_array($attributes[$user_attr_cas_group])) {
                $attributes[$user_attr_cas_group]=[$attributes[$user_attr_cas_group]];
            }
            foreach($attributes[$user_attr_cas_group] as $ssogroup) {
                // Recherche du groupe
                $group=$em->getRepository("App\Entity\Group")->findOneBy(["label"=>$ssogroup]);
                if(!$group) {
                    $group=new Group();
                    $group->setLabel($ssogroup);
                    $group->setFgcancreatepage(false);
                    $group->setFgcancreateblog(false);
                    $group->setFgcancreatecalendar(false);
                    $group->setFgcancreateproject(false);
                    $group->setFgcanshare(false);
                    $group->setFgopen(false);
                    $group->setFgall(false);
                }
                $group->setAttributes('{"'.$user_attr_cas_group.'":"'.$ssogroup.'"}');
                $group->setFgtemplate(false);
                $em->getManager()->persist($group);
                $em->getManager()->flush();
            }
        }
    }

    private function replaceContent($content) {
        return str_replace("/".$this->getParameter("alias")."uploads/ckeditor/",$this->getParameter("protocole")."://".$this->getParameter("weburl")."/".$this->getParameter("alias")."uploads/ckeditor/",$content);

    }

    private function getHost($request) {
        $host = $request->getHost();
        $protocol = $request->getScheme();

        return $protocol."://".$host;
    }    
}



