<?php
/**
 * DokuWiki Plugin asana (Action Component)
 *
 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
 * @author  pierre Viloutreix <pierre@elonet.fr>
 */

include "asana_fcts.php";
include "../../../../inc/plugins.php";
include "../../remote.php";
//include "/usr/share/dokuwiki/inc/plugin.php";
//include "/usr/share/dokuwiki/lib/plugins/remote.php";

// must be run within Dokuwiki
if (!defined('DOKU_INC')) die();

class remote_plugin_asana_APILink extends DokuWiki_Remote_Plugin {

    //url de l'API d'Asana, on la garni en fonction de la requete
    var $url_base = "https://app.asana.com/api/1.0";
    
   
    var $api_key = "";
    
    //initialisation de l'objet de requete utilisant curl
    var $ch;
    
    //workspace par default
    var $workspace = "";
    
    //text to render
    var $text = "";
    
    var $workspaces = array();
    
    var $projects = array();
    
    var $assignees = array();
    
    var $tags = array();
    
    var $workspace_filter = array();
    
    
    var $assignees_filter= array();
    
    
    var $tags_filter= array();
    
    
    var $projects_filter = array();
    
    var $strings_filter = array();
    
    /**
     * Construct curl object to collecte Asana's intelligences
     * Api from this user in prameter
     **/
    public function __construct(){
        //echo "Initialisation de l'objet CURL\n";
        $this->ch= curl_init();
        //obtenir la réponse comme un return
        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER , true);
        //définie le header de la requete
        curl_setopt($this->ch, CURLOPT_HTTPHEADER , array('Content-type: application/json'));
        //définie option ssl
        curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER , FALSE);
        
        
    }
    
    public function __destruct(){
        curl_close($this->ch);
    }
    
    
    /**
     * Register RPC methods and their arguments
     */
    public function _getMethods() {
        return array(
            
            'plugin.asana.connecte' => array(
                'args'   => array('string'),
                'return' => 'string',
                'doc'    => "Connecte un user à son compte Asana via sa clé API"
            ),
            'plugin.asana.render_user' => array(
                'args'   => array('string'),
                'return' => 'string',
                'doc'    => "Donne le rendu des taches Asana d'un user sous forme d'un tableau"
            )
        );
    }


    /**
     * Connection à l\'api via la demande de clé api pour le site Asana
     **/
     function connect(){
         $api_key_user = $this->getConf('api_key');
         //echo "Définition de la clé API\n";
         if( $api_key_user != "Asana's API key"){
            $this->api_key = $api_key_user;
        }
        else {
            return "<p> Vous devez spécifier une clé API d'Asana depuis le menu de configuration du plugin Asana.</p>";
        }
        //définie l'utilisateur et mdp ( ici pas de mdp)
        curl_setopt($this->ch, CURLOPT_USERPWD , $this->api_key . ":");
        
        
        $this->workspaces = $this->workspaces();
        
        //ici on ira cherché le workspace contenu dans la partie conf
        foreach( $this->workspaces as $work_key => $work_value ){
            if( $work_key == $this->getConf('workspace')){
                $this->workspace_filter['name']= $work_key;
                $this->workspace_filter['id']=$work_value;
            }
        }
        
        if(!empty($this->workspace_filter)){
            $this->projects = $this->workspace_projects($this->workspace_filter['id']);
            $this->assignees = $this->workspace_users($this->workspace_filter['id']);
            $this->tags = $this->workspace_tags($this->workspace_filter['id']);
        }
        return "";
    }
    
    /*
    /**
     * render le tableau contenant les infromations sur les taches
     * le format du render text est surrement à modifier
     
     **/
    function render_user(){
        if(empty($this->workspace_filter)){
            return "<p>Vous devez spécifier un nom de workspace. Soit dans la configuration du plugin. Soit dans la syntaxe.</p>";
        }
        else{
            $text = "<div>";
            $text = $text . "<h1> Tâches Asana ( Asana's Tasks ) </h1><br/>";
            $text = $text . "<h2>". $this->workspace_filter['name'] . "</h2><br/>";
            $text = $text . "<table>".$this->render_workspaces($this->workspace_filter['id'])."</table>";
            $text = $text . "<br/><br/>";
            return $text."</div>";
        }
    }
    
    /**
     * render un worspace, c'est à dire créé un tableau
     * met dans text les données structurant le tableau
     **/
     
    function render_workspaces($workspace){;
        $text =  "<tr><td>Project</td><td> Task Name</td><td> Assignee </td><td> Due date </td><td> Comments/Tags </td></tr>";
        $tasks = array();
        if( empty($this->assignees_filter)){
            if(empty($this->projects_filter)){
                //non assignee non project
                $this->projects = $this->workspace_projects($workspace);
                foreach( $this->projects as $project_key => $project_value ){
                    $tasks_current = $this->project_tasks($project_value);
                    foreach($tasks_current as $task_key => $task_value){
                        $task_value['project']=$project_key;
                        $tasks_current[$task_key]=$task_value;
                    } 
                    $tasks = array_merge($tasks,$tasks_current);
                    
                }
            }
            else{
                //non assignee project
                foreach( $this->projects_filter as $project_key => $project_value){
                    $tasks_current = $this->project_tasks($project_value);
                    foreach($tasks_current as $task_key => $task_value){
                        $task_value['project']=$project_key;
                        $tasks_current[$task_key]=$task_value;
                    } 
                    $tasks = array_merge($tasks,$tasks_current);
                }
            }
        }
        else{
            if(empty($this->projects_filter)){
                //assignee non project
                foreach( $this->assignees_filter as $assignee){
                    foreach( $this->projects as $project_key => $project_value ){
                        $tasks_current = $this->project_tasks_assignee($project_value, $assignee);
                        foreach($tasks_current as $task_key => $task_value){
                            $task_value['project']=$project_key;
                            $tasks_current[$task_key]=$task_value;
                        }  
                        $tasks = array_merge($tasks,$tasks_current);
                    }
                }
            }
            else{
                //assignee project
                foreach( $this->projects_filter as $project_key => $project_value){
                    foreach( $this->assignees_filter as $assignee){
                        $tasks_current = $this->project_tasks_assignee($project_value,$assignee);
                        //var_dump($tasks_current);
                        foreach($tasks_current as $task_key => $task_value){
                            $task_value['project']=$project_key;
                            $tasks_current[$task_key]=$task_value;
                        } 
                        
                        $tasks = array_merge($tasks,$tasks_current);
                    }
                }
            }
        }
        if( !empty($this->tags_filter)){
            foreach($this->tags_filter as $tag_key => $tag_value){
                $tasks = $this->tag_filter($tag_key,$tasks);
            }
        }
        
        if( !empty($this->strings_filter)){
            foreach($this->strings_filter as $string){
                $tasks = $this->string_filter($string, $tasks);
            }
        }
        
        $tasks = $this->due_date_sort($tasks);
        foreach(  $tasks as $task){
                $text .=  "<tr><td> ".$task['project'] . " </td><td> " . "<a href='https://app.asana.com/0/".$this->project_find($this->projects_filters,$task['project'])."/".$task['id']."' target='_blank'>".$task['name'] ."</a>". " </td><td> " .$task['assignee']['name'] . " </td><td> " . $task['due_date'] . " </td><td> " . $this->comment_head($task['id'],$this->render_comments($task['id']).$this->render_tags($task['tags']))." </td></tr>";
        }
        return $text;
    }
    
    
    
    
    /*
     * donne le code html pour afficher les commentaires de chaque tâches
     * on affiche une fenêtre modale contenant les commentaires sous forme de liste
     **/
    function comment_head($div_id,$text){
        return "<html>
                    <style>
                    #comment".$div_id."{
                        display: none;
                        position: fixed;
                        top:0;
                        right:0;
                        bottom:0;
                        left:0;
                        background-color: rgba(0, 0, 0, 0.5);
                        z-index: 1000;
                    }
                    #comment".$div_id.":target{
                        display: block;
                    }
                    #comment".$div_id." a{
                        font-weight: bold;
                        padding: 10px 25px;
                        background-color: white;
                        position: absolute;
                        top: 25%;
                        left: 50px;
                    }
                    </style>
                    <div id='comment".$div_id."'>
                        <a href='#noWhere' ><p>Fermer les commentaires</p>".$text."</a>
                    </div>
                    <p><a href='#comment".$div_id."'>Afficher le masque</a></p>
                </html>";
   
    }
    
    
    
     /* render des commentaires d'une tache
     * liste des textes des commentaires
     **/
    
    function render_comments($task){
        $text = "<h2>Comments :</h2>";
        $text .= "<ul>";
        foreach( $this->task_comments($task) as $comment_key => $comment_value){
            $text = $text . "<li>" . $comment_key . "</li>";
        }
        
        return $text."</ul>";
    } 
    
    
    /**
     * render des tags
     * liste des noms de tags
     **/
     
    function render_tags($tags){
        $text = "<h2>Tags :</h2>";
        $text .= "<ul>";
        foreach( $tags as $tag){
            $text = $text . "<li>" . $tag['name'] . "</li>";
        }
        return $text."</ul>";
    }
    
 
    function addProjectFilter($project_target_name){
        foreach($this->projects as $project_key => $project_value){
            if($project_key==$project_target_name){
               $this->projects_filter[$project_key]=$project_value;
               return 1;
           }
       } 
       return 0;
    } 
    
    function addAssigneeFilter($assignee_target_name){
        foreach($this->assignees as $assignee_key => $assignee_value){
            if($assignee_key==$assignee_target_name){
               $this->assignees_filter[$assignee_key]=$assignee_value;
               return 1;
           }
       } 
       return 0;
    }
    
    function addTagFilter($tag_target_name){
        foreach($this->tags as $tag_key => $tag_value){
            if($tag_key==$tag_target_name){
               $this->tags_filter[$tag_key]=$tag_value;
               return 1;
           }
       } 
       return 0;
    }
    
    function addStringFilter($string_filter){
        $this->strings_filter[]= $string_filter;
    }
    
    function changeWorkspace($workspace_target_name){
        foreach($this->workspaces as $work_key => $work_value){
            if( $work_key == $workspace_target_name){
                $this->workspace_filter = array( 'name' => $work_key , 'id' => $work_value );
                $this->projects = $this->workspace_projects($this->workspace_filter['id']);
                $this->assignees = $this->workspace_users($this->workspace_filter['id']);
                $this->tags = $this->workspace_tags($this->workspace_filter['id']);
                return 1;
            }
        }
        return 0;
    }
    
    //donne la liste des workspace de l'utilisateur courant
    function workspaces(){
         curl_setopt($this->ch, CURLOPT_URL , $this->url_base."/users/me");
         $data_rep = json_decode(curl_exec($this->ch),true);
         //var_dump($data_rep);
         $workspaces = array();
         foreach($data_rep['data']['workspaces'] as $workspace){
            $workspaces[$workspace['name']]=$workspace['id'];
         }
         return $workspaces;
    }
    
    // donne la liste des utilisateur du workspace spécifié
    // retourne la liste sous forme clé : nom, valeur : id
    function workspace_users($workspace_ID){
		curl_setopt($this->ch, CURLOPT_URL , $this->url_base."/workspaces/".$workspace_ID."/users");
		$data_rep = json_decode(curl_exec($this->ch),true);
		$users = array();
		foreach($data_rep['data'] as $nom){
			$users[$nom['name']]=$nom['id'];
		}
		return $users;
    }
    
    //donne les projets d'un workspace donné
    function workspace_projects($workspace_ID){
		curl_setopt($this->ch, CURLOPT_URL , $this->url_base."/workspaces/".$workspace_ID."/projects");
		$data_rep = json_decode(curl_exec($this->ch),true);
		//var_dump($data_rep);
		$projects = array();
		foreach($data_rep['data'] as $project){
			$projects[$project['name']]=$project['id'];
		}
		
		return $projects;
    }
    
    function workspace_tags($workspace_ID){
        curl_setopt($this->ch, CURLOPT_URL , $this->url_base."/workspaces/".$workspace_ID."/tags");
        $data_rep = json_decode(curl_exec($this->ch),true);
        //var_dump($data_rep);
        $tags = array();
        foreach($data_rep['data'] as $tag){
                $tags[$tag['name']]=$tag['id'];
        }
        return $tags;
    }
    
    //donne les tache d'un project selon un assignee
    function project_tasks_assignee($project_ID,$assignee_id){
            $data_rep = $this->project_tasks($project_ID);
            $tasks = array();
            foreach($data_rep as $task){
                if( $task['assignee']['id'] == $assignee_id ){
                    $tasks[]=$task;
                }
            }
            
            return $tasks;
    }


    //donne les tache d'un projet donné
    function project_tasks($project_ID){
            curl_setopt($this->ch, CURLOPT_URL , $this->url_base."/projects/".$project_ID."/tasks");
            $data_rep = json_decode(curl_exec($this->ch),true);
            //var_dump($data_rep);
            $tasks = array();
            foreach($data_rep['data'] as $task){
                $tasks[]=$this->task($task['id']);
            }
            return $tasks;
    }

    //donne les détails d'un tache donné
    function task($task_ID){
            curl_setopt($this->ch, CURLOPT_URL , $this->url_base."/tasks/".$task_ID);
            $data_rep = json_decode(curl_exec($this->ch),true);
            //var_dump($data_rep);
            $task = array();
            $task_elt = $data_rep['data'];
            $task=array( 'id' => $task_elt['id'] , 'name' =>$task_elt['name'], 'tags' => $task_elt['tags'], 'due_date' => $task_elt['due_on'], 'assignee' => $task_elt['assignee'], 'desc' => $task_elt['notes']);
            return $task;
    }


    //donne les commentaires d'une tache
    function task_comments($task_ID){
        curl_setopt($this->ch, CURLOPT_URL, $this->url_base."/tasks/".$task_ID."/stories");
        $data_rep = json_decode(curl_exec($this->ch),true);
        $comments = array();
        foreach( $data_rep['data'] as $storie){
            if($storie['type'] == 'comment'){
                $comments[$storie['text']] = $storie['id'];
            }
        }
        return $comments;
    }
    
    //fonction de comparaison de deux date dans un tableau de taches
    static function compare_date($task1, $task2){
        date_default_timezone_set("UTC");
        
        if( $task1['due_date'] == "" ){
            //si la date 1 n'existe pas
            if( $task2['due_date'] == "" ){
                //si la date 2 n'existe pas
                return 0;
            }
            else{
                //si la date 2 existe
                return 1;
            }
        }
        else{
            //si la date 1 existe
            if( $task2['due_date'] == "" ){
                //si la date 2 n'existe pas
                return -1;
            }
            else{
                // les deux dates existent donc on les comparent vraiment
                $date1 = strtotime($task1['due_date']);
                $date2 = strtotime($task2['due_date']);
                if( $date1<$date2){
                    return -1;
                }
                elseif( $date1 == $date2){
                    return 0;
                }
                else{
                    return 1;
                }
            }
        }
    }

    // trie un tableau de taches par leur deadline
    function due_date_sort($tasks){
        uasort($tasks,array('remote_plugin_asana_APILink','compare_date'));
        return $tasks;
    }
    
    //permet de trouver l'id du projet dans le workspace selon le nom du projet
    function project_find($projects,$project_target_name){
        foreach( $projects as $project_name => $project_id ){
            if( $project_name == $project_target_name){
                return $project_id;
            }
        }
        return 0;
    }
    
    function string_filter($string, $tasks){
        $tasks_cp = array();
        while( count($tasks) !=0 ){
            $task = array_shift($tasks);
            if(strstr($task['name'],$string) or strstr($task['desc'],$string)){
                $tasks_cp[] = $task;
            }
        }
        return $tasks_cp;
    }
    
    //filtre un tableau de tache selon un tag
    function tag_filter($tag_name, $tasks){
        $tasks_cp = array();
        while( count($tasks) !=0 ){
            $task = array_shift($tasks);
            if($this->tags_compare($tag_name,$task) == 1){
                $tasks_cp[] = $task;
            }
        }
        return $tasks_cp;
    }

    //compare le tag d'une tache à un nom de tag
    function tags_compare($tag_name,$task){
        foreach( $task['tags'] as $tag ){
            if( $tag['name'] == $tag_name ){
                return 1;
            }
        }
        return 0;
    }
    
}


