<?php

define('ALC_API', '1');

require '../api.php';

if(!class_exists('AwesomeLiveChat_API')) die('-1');

if(class_exists('AwesomeLiveChat_API_Visitor')) die('-1');

class AwesomeLiveChat_API_Visitor extends AwesomeLiveChat_API
{
    public function __construct()
    {
        parent::__construct('json', true);
    }

    private function ping($sleep)
    {
        if($sleep % 10) return false;
        return $this->_->operatorPing($this->auth_id);
    }

    protected function authenticate()
    {
        $token = false;
        if($this->auth_token)
        {
            $this->auth_id = $this->_->operatorID($this->auth_token);
            if($this->auth_id) return true;
            $token = true;
        }
        $this->auth_id = $this->_->authenticateOperator(
            $this->username, $this->password
        );
        if(!$this->auth_id)
            $this->response(
                ('Invalid ' . ($token ? 'token' : 'credentials')),
                $this->HTTP->HTTP_UNAUTHORIZED
            );
        if($this->auth_id == -1)
            $this->response(
                'Permission denied',
                $this->HTTP->HTTP_UNAUTHORIZED
            );
        $this->auth_token = $this->_->operatorToken($this->auth_id);
        return true;
    }

    protected function validateVisitor()
    {
        $this->id = $this->_->getVisitor('id', 'token', $this->token);
        if(!$this->id)
            $this->response(
                'Could not validate visitor',
                $this->HTTP->HTTP_BAD_REQUEST
            );
    }

    public function post_auth()
    {
        $Operator = get_userdata($this->auth_id);
        $this->response(array(
            'token'    => $this->auth_token,
            'name'     => $Operator->display_name,
            'gravatar' => $this->_->gravatarOperator(
                $this->auth_id,
                $Operator->user_email
            ), 'departments' => $this->_->getOperator(
                $this->auth_id, 'alc_departments'
            )
        ), $this->HTTP->HTTP_OK);
    }

    public function get_auth()
    {
        $Operator = get_userdata($this->auth_id);
        $this->response(array(
            'token'    => $this->auth_token,
            'name'     => $Operator->display_name,
            'gravatar' => $this->_->gravatarOperator(
                $this->auth_id,
                $Operator->user_email
            ), 'departments' => $this->_->getOperator(
                $this->auth_id, 'alc_departments'
            )
        ), $this->HTTP->HTTP_OK);
    }

    public function get_socket()
    {
        $Socket = $this->_->settings('socket');
        $this->response(
            $Socket ? $Socket : array(),
            $this->HTTP->HTTP_OK
        );
    }

    public function get_visitors()
    {
        $quick = $this->get('quick', false);
        settype($quick, 'bool');

        $raw = $this->get('raw', false); // by server
        settype($raw, 'bool');

        # request for waiting ids
        $ids = $this->get('wd', null);
        $Ids = $ids
            ? array_map('intval', array_map('trim', explode('.', $ids)))
            : array();
        $Users = array();
        # => done? filter ids and send done ids
        $Done = array();
        # => stolen? filter ids and send stolen ids
        $Stolen = array();
        # => welcome visitor if welcomed by alias.
        $Welcome = array();

        $this->ping(10);
        $sleep = 0;
        do {
            if($sleep++) sleep(1);
            if($this->timeout < $sleep)
                break;
            $this->ping($sleep);
            $_Users = $this->_->operatorVisitors(
                $this->auth_id,
                array('waiting', 'busy', 'done'),
                0
            );
            $_Ids = array();
            foreach($_Users as $User)
            {
                // users
                if($User->id > (int) $this->get('offset', 0))
                {
                    // get country flag
                    $User->flag = $this->_->getFlag($User->cc);
                    // push user
                    $Users[] = $User;
                }
                 // previous ones
                else if(!$raw)
                {
                    // in hand
                    $_Ids[] = (int) $User->id;
                    if($User->status == 'waiting' || $User->status == 'busy')
                    {
                        $online = $this->_->isVisitorOnline(
                            $User->id, $User->status, $User->ping
                        );
                        if(!$online)
                            $Done[] = $User->token;
                    }
                    else if($User->status == 'done' && !in_array($User->id, $Ids))
                        $Done[] = $User->token;

                    if($User->status == 'busy' && in_array($User->id, $Ids))
                    {
                        $Welcome[] = $User->token;
                    }
                }
            }
            // stolen ids
            $_Stolen = array_diff($Ids, $_Ids);
            $Stolen = $this->_->visitorsTokens($_Stolen);
            if($quick) break;
        } while (!$Users && !$Done && !$Stolen && !$Welcome);

        $Response = array();
        if($Users) $Response['users'] = $Users;
        # send back the user ids that are done
        if($Done)  $Response['done']  = $Done;
        # send back the user ids that are stolen
        if($Stolen)  $Response['stolen']  = $Stolen;
        # send back the user ids that are welcomed (by aliases)
        if($Welcome)  $Response['welcome']  = $Welcome;
        $this->response($Response, $this->HTTP->HTTP_OK);
    }

    public function get_chat()
    {
        $quick = $this->get('quick', false);
        settype($quick, 'bool');

        $seen = $this->get('currently');
        if(!empty($seen)) $this->_->operatorSaw(
            $this->auth_id,
            $this->_->getVisitor('id', 'token', $seen)
        );
        $Chat = array();
        $this->ping(10);
        $sleep = 0;
        do {
            if($sleep++) sleep(1);
            if($this->timeout < $sleep)
                break;
            $this->ping($sleep);
            $Chat = $this->_->operatorChat(
                $this->auth_id, array('busy', 'done'), $this->get('offset', 0)
            );
            if($quick) break;
        } while (!$Chat);
        $this->response(array('chat' => $Chat), $this->HTTP->HTTP_OK);
    }

    public function post_message()
    {
        $this->validateVisitor();
        $this->_->operatorSaw($this->auth_id, $this->id);
        $message = $this->post('message');
        $guid = $this->post('guid', '');
        if(empty($message))
        {
            $this->response(
                'Message can not be empty',
                $this->HTTP->HTTP_OK//HTTP_BAD_REQUEST
            );
        }
        $this->response(array($this->_->postChat(
                $this->id,
                $this->auth_id,
                (strip_tags($message)),
                1, // operator
                $guid // backbonejs id
            )), $this->HTTP->HTTP_OK
        );
    }

    public function post_welcome()
    {
        $this->validateVisitor();
        $this->response(
            $this->_->operatorWelcome(
                    $this->auth_id,
                    $this->id,
                    $this->token
            ), $this->HTTP->HTTP_OK
        );
    }

    public function post_seen()
    {
        $this->validateVisitor();
        $this->_->operatorSaw($this->auth_id, $this->id);
        $this->response(array(true), $this->HTTP->HTTP_OK);
    }

    public function post_end()
    {
        $this->validateVisitor();
        $this->_->operatorSaw($this->auth_id, $this->id);
        $this->_->setVisitor(
            'status',
            'id',
            (int) $this->id,
            (string) 'done'
        );
        $this->response(array(true), $this->HTTP->HTTP_OK);
    }

    public function post_archive()
    {
        $this->validateVisitor();
        $this->_->setVisitor(
            'status',
            'id',
            (int) $this->id,
            (string) 'archive'
        );
        $this->response(array(true), $this->HTTP->HTTP_OK);
    }

    // for socket
    public function post_ping()
    {
        $this->response($this->ping(10), $this->HTTP->HTTP_OK);
    }
}

new AwesomeLiveChat_API_Visitor();

exit;