<?php
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
$unique_users = [];
$context = array(
    'ssl' => array(
        'local_cert'  => __DIR__ . '/privatessl/cert.pem',
        'local_pk'    => __DIR__ . '/privatessl/key.key',
        'verify_peer' => false,
    )
);
// Create a Websocket server with ssl context.
$ws_worker = new Worker('websocket://website.ru:6374', $context);
$ws_worker->transport = 'ssl';
$ws_worker->onMessage = function ($connection, $data) use ($ws_worker, &$unique_users) {
    $response = json_decode($data);
    ## Команды ##
    if (isset($response->command)) {
        ## Получение пользователей онлайн ##
        if ($response->command == 'getOnline') {
            $connection->send(getOnline($unique_users));
        }
        ## Отправка нового сообщения ##
        if ($response->command == 'sendMessage' && isset($response->message) && !empty($response->message)) {
            sendMessage(
                $response->message,
                $response->login,
                $response->avatar,
                $ws_worker,
                $connection
        );
        }
    }
};
$ws_worker->onConnect = function($connection) use (&$unique_users)
{
    $ip = $connection->getRemoteIp();
    if (!in_array($ip, $unique_users))
    {
        $unique_users[] = $ip;
    }
};
$ws_worker->onClose = function($connection) use (&$unique_users)
{
    $ip = $connection->getRemoteIp();
    $index = array_search($ip, $unique_users);
    unset($unique_users[$index]);
};
function getOnline($unique_users)
{
    $online = [
        'action' => 'online',
        'body' => count($unique_users),
    ];
    return json_encode($online);
}
function sendMessage($message,$login, $avatar, $worker, $connection)
{
    $body = [
        'action' => 'newMessage',
        'body' => $message,
        'login' => $login,
        'avatar' => $avatar,
        'time' => date('d.m.Y в H:i', (time() + 10800))
    ];
    foreach ($worker->connections as $client) {
        $client->send(json_encode($body));
    }
    addMessageDB($message, $login, $avatar);
}
function prepareText($text)
{
    return htmlspecialchars($text);
}
function addMessageDB($message, $login, $avatar){
    $db_config = require(__DIR__ . '/config/db.php');
    $db = new PDO($db_config['dsn'] . ';charset=' . $db_config['charset'], $db_config['username'], $db_config['password']);
    $sth = $db->prepare('INSERT INTO chat_message (message, created_at, login, avatar) VALUES (:mess, :create_time, :login, :avatar)');
    $sth->execute([
        ':mess' => prepareText($message),
        ':create_time' => time(),
        ':login' => prepareText($login),
        ':avatar' => prepareText($avatar),
    ]);
    return $sth->fetchAll(PDO::FETCH_ASSOC);
}
Worker::runAll();