<?php

namespace Admin;

use Shared\Messages;
use Watcher\DBTorrent;
use Watcher\DBuTorrentClient;


class AdminREST extends \Shared\AbstractREST
{
#region path and method mappings

    
protected function getRespond($data)
    {
        switch($this->class)
        {
            case "users": return $this->usersGetRespond($data);
            default: http_response_code(403);die();
        }
    }

    protected function postRespond($data)
    {   
        switch($this->class)
        {
            case "users": return $this->usersPostRespond($data);
            case "clients": return $this->clientsPostRespond($data);
            case "distlist": return $this->distListPostRespond($data);
            default: http_response_code(403);die();
        }
    }

    protected function deleteRespond($data)
    {
        switch($this->class)
        {
            case "users": return $this->usersDeleteRespond($data);
            case "clients": return $this->clientsDeleteRespond($data);
            case "distlist": return $this->distListDeleteRespond($data);
            default: http_response_code(403);die();
        }
    }

    protected function putRespond($data)
    {
        switch($this->class)
        {
            case "users": return $this->usersPutRespond($data);
            case "clients": return $this->clientsPutRespond($data);
            case "distlist": return $this->distListPutRespond($data);
            default: http_response_code(403);die();
        }
    }
    #endregion path and method mappings
   
    //aktualizace záznamu torrentu v distribuci  
      protected function distListPutRespond($updatedDistr)
    {
        $dbdistr=\Shared\DBTorrentToDistribute::GetTorrentDistributionByID($this->id);
        $dbdistr->Active =$updatedDistr["Active"]?1:0;

        if(isset($updatedDistr["groups"]) && is_array($updatedDistr["groups"]))
                    {
                        foreach($updatedDistr["groups"] as $gr)//pridani nových skupin
                        {
                            if(!in_array($gr,$dbdistr->Groups))
                            {
                                if($dbdistr->AddGroupByName($gr))
                                    \Shared\Messages::Information("Group ".$gr." assigned.");
                            }
                        }
                        foreach($dbdistr->Groups as $clgr)//odebraání smazaných skupin
                        {
                            if(!in_array($clgr,$updatedDistr["groups"]))
                            {
                                $dbdistr->RemoveGroup($clgr);
                                \Shared\Messages::Information("Group ".$clgr." removed.");
                            }
                        }
                    }
        return $dbdistr->SaveAllData();
    }
    //aktualizace klienta
    protected function clientsPutRespond($data)
    {
       
        if($this->id >0)
        {
            switch ($this->subclass)
            {
                case "torrents": return $this->clientsPutTorrentResponse($data);
                default : 

                    $client= \Watcher\DBuTorrentClient::GetById($this->id);
                    if(isset($data["active"]) && $data["active"]!=$client->Active )
                    {
                        $client->Active=$data["active"]==1;var_dump($client);                      
                    }
                    if(isset($data["groups"]) && is_array($data["groups"]))
                    {
                        foreach($data["groups"] as $gr)//pridani nových skupin
                        {
                            if(!in_array($gr,$client->Groups))
                            {
                                $client->AddGroupByName($gr);
                                \Shared\Messages::Information("Group ".$gr." assigned.");
                            }
                        }
                        foreach($client->Groups as $clgr)//odebraání smazaných skupin
                        {
                            if(!in_array($clgr,$data["groups"]))
                            {
                                $client->RemoveGroup($clgr);
                                \Shared\Messages::Information("Group ".$clgr." removed.");
                            }
                        }
                    }
                    $client->UpdateOrSave();

                break;
            }
 
        }
    }
    //aktualizace záznamu torrentu na klientu 
    private function clientsPutTorrentResponse($updatedTorrent)
    {
        $torrentInDB = \Watcher\DBTorrent::GetTorrentByID($this->subID);
        //pause
        if($torrentInDB[\Watcher\DBTorrent::$colPaused]!=1 && $updatedTorrent["paused"])
        {
                $clientApi = new \Commander\UTorrentClient($torrentInDB[\Watcher\DBTorrent::$colClientAddress], $torrentInDB[\Watcher\DBTorrent::$colClientPort]);
                $clientApi->ConnectApi()->torrentPause($torrentInDB[\Watcher\DBTorrent::$colHash]);
                \Shared\Messages::Information("Pause command has been sent to client");
        }
        //resume
        if($torrentInDB[\Watcher\DBTorrent::$colPaused]==1 && !$updatedTorrent["paused"])
        {
                $clientApi = new \Commander\UTorrentClient($torrentInDB[\Watcher\DBTorrent::$colClientAddress], $torrentInDB[\Watcher\DBTorrent::$colClientPort]);
                $clientApi->ConnectApi()->torrentStart($torrentInDB[\Watcher\DBTorrent::$colHash]);
                \Shared\Messages::Information("Start command has been sent to client");
        }
          //start
        if($torrentInDB[\Watcher\DBTorrent::$colStarted]!=1 && $updatedTorrent["started"])
          {
                  $clientApi = new \Commander\UTorrentClient($torrentInDB[\Watcher\DBTorrent::$colClientAddress], $torrentInDB[\Watcher\DBTorrent::$colClientPort]);
                  $clientApi->ConnectApi()->torrentStart($torrentInDB[\Watcher\DBTorrent::$colHash]);
                  \Shared\Messages::Information("Start command has been sent to client");
          }

        return true;
    }

    private function clientsDeleteTorrentResponse($data)
    {
        
        $torrentInDB =  \Watcher\DBTorrent::GetTorrentByID($this->subID);
        $clientApi = new \Commander\UTorrentClient($torrentInDB[\Watcher\DBTorrent::$colClientAddress],$torrentInDB[\Watcher\DBTorrent::$colClientPort]);//var_dump($torrentInDB[\Watcher\DBTorrent::$colClientAddress]);
        $res=false;
        if(\Shared\Settings::$AdminRemoveWithFiles)
            $res=$clientApi->ConnectApi()->torrentDataRemove($torrentInDB[\Watcher\DBTorrent::$colHash]);
        $res&=$clientApi->ConnectApi()->torrentRemove($torrentInDB[\Watcher\DBTorrent::$colHash]);
        if($res)
            \Shared\Messages::Information("Remove command has been sent to client");
        else
        {
            \Shared\Messages::Information("Remove command failed:".$res);
        }
        return true;
    }
    ///nový záznam do distribučního listu
    private function distListPostRespond($data)
    {
        $data=json_decode($data["newTorrent"],true);

        $replaced=str_replace("data:application/x-bittorrent;base64,","",$data["data"]);

        $data["data"]=base64_decode(str_replace(' ', '+', urldecode($replaced)));

        $distListItem = new \Shared\DBTorrentToDistribute($data);
        
        $distListItem->SaveAllData();
        \Shared\Messages::Information("Torrent added with id ". $distListItem->Id.".");

        foreach($data["groups"] as $grouptoadd)
        {
            $distListItem->AddGroupByName($grouptoadd);
            \Shared\Messages::Information("Group ".$grouptoadd." assigned.");
        }
    }   
    //změna záznamu v distribučním listu
    private function distListDeleteRespond($data)
    {
	
        if($this->id!=null)
        {
            $torr=\Shared\DBTorrentToDistribute::GetTorrentDistributionByID($this->id);
            return $torr->Delete();
        }
    }

    private function usersPutRespond($data)
    {

        if($this->id!=null)
        {
            $userdata=array(
                \Shared\DBUser::$colUserName =>$data["username"],
                \Shared\DBUser::$colDisplayName=>$data["displayname"],
                \Shared\DBUser::$colType=>$data["type"],
                \Shared\DBUser::$colDomain=>$data["domain"],
                \Shared\DBUser::$colActive=>$data["active"]?1:0,
                \Shared\DBUser::$colAdmin=>$data["admin"]?1:0);
                if(isset($data["password"]))
                    $userdata[\Shared\DBUser::$colPasswordHash]=password_hash($data["password"],PASSWORD_BCRYPT);
                //var_dump($userdata);

            return \Shared\DBUser::UpdateOrSave($this->id, $userdata);
        }
    }

    private function usersGetRespond($data)
    {
        if($this->id==null)
        {
            $list=\Shared\DBUser::GetAllUsersFromDB();
            foreach($list as $key=>$value)
            {
                unset($list[$key][\Shared\DBUser::$colPasswordHash]);
            }
            return $list;
        }
        else
            {
            $user= \Shared\DBUser::GetUserByID($this->id);
            unset($user[\Shared\DBUser::$colPasswordHash]);
            return $user;
            }
    }

    //vytvoření nového záznamu klienta
    private function usersPostRespond($data)
    {
        $data=json_decode($data["newUser"],true);
        
        $userdata=array(
            \Shared\DBUser::$colUserName =>$data["username"],
            \Shared\DBUser::$colDisplayName=>$data["displayname"],
            \Shared\DBUser::$colType=>$data["type"],
            \Shared\DBUser::$colDomain=>$data["domain"],
            \Shared\DBUser::$colActive=>$data["active"]?1:0,
            \Shared\DBUser::$colPasswordHash=>password_hash($data["password"],PASSWORD_BCRYPT),
            \Shared\DBUser::$colAdmin=>$data["admin"]?1:0);var_dump($userdata);
        return \Shared\DBUser::UpdateOrSave(null, $userdata);
    }

    private function usersDeleteRespond($data)
    {
        return \Shared\DBUser::Delete($this->id);
    }

    private function clientsPostRespond($data)
    {
        $data=json_decode($data["newClient"],true);
        foreach(explode(";",$data["address"]) as $singleAddress)
        {
            $matchgroups=array();
            $clientData=$data;
            //ip range
            if(preg_match("/^(([\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.)([\d]{1,3}))-([\d]{1,3})$/",$singleAddress,$matchgroups))
            {
                
                if($matchgroups[3]>=$matchgroups[4])
                {
                \Shared\Messages::Error("Specified range must be ascending ".$singleAddress."");return;
                }
                for($i=$matchgroups[3];$i<=min(255,$matchgroups[4]);$i++)
                    {
                        $clientData["address"]=$matchgroups[2].$i;
                        $client= new \Watcher\DBuTorrentClient($clientData);

                        $client->UpdateOrSave();
                        \Shared\Messages::Information("Client ".$clientData["address"]." added.");
                        foreach($data["groups"] as $grouptoadd)
                        {
                            $client->AddGroupByName($grouptoadd);
                            \Shared\Messages::Information("Group ".$grouptoadd." assigned.");
                        }
                    }

            }
            else
            {
                $clientData["address"]=$singleAddress;
                $client= new \Watcher\DBuTorrentClient($clientData);

                $client->UpdateOrSave();
                \Shared\Messages::Information("Client ".$singleAddress." added.");

                foreach($data["groups"] as $grouptoadd)
                {
                    $client->AddGroupByName($grouptoadd);
                    \Shared\Messages::Information("Group ".$grouptoadd." assigned.");
                }
            }
        } //\Shared\Messages::Error("test");
    }

    private function clientsDeleteRespond($data)
    {
        if($this->subclass=="torrents")
            return $this->clientsDeleteTorrentResponse($data);

        $res=\Watcher\DBuTorrentClient::Delete($this->id);
        \Shared\Messages::Information("Client ".$this->id." deleted.");
        return $res;
    }

}