/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "config.h"

#include "guacamole/client.h"
#include "guacamole/error.h"
#include "guacamole/socket.h"
#include "guacamole/user.h"

#include <pthread.h>
#include <stdlib.h>

/**
 * Data associated with an open socket which writes to all connected users of
 * a particular guac_client.
 */
typedef struct guac_socket_broadcast_data {

    /**
     * The guac_client whose connected users should receive all instructions
     * written to this socket.
     */
    guac_client* client;

    /**
     * Lock which is acquired when an instruction is being written, and
     * released when the instruction is finished being written.
     */
    pthread_mutex_t socket_lock;

} guac_socket_broadcast_data;

/**
 * Single chunk of data, to be broadcast to all users.
 */
typedef struct __write_chunk {

    /**
     * The buffer to write.
     */
    const void* buffer;

    /**
     * The number of bytes in the buffer.
     */
    size_t length;

} __write_chunk;

/**
 * Callback which handles read requests on the broadcast socket. This callback
 * always fails, as the broadcast socket is write-only; it cannot be read.
 *
 * @param socket
 *     The broadcast socket to read from.
 *
 * @param buf
 *     The buffer into which data should be read.
 *
 * @param count
 *     The number of bytes to attempt to read.
 *
 * @return
 *     The number of bytes read, or -1 if an error occurs. This implementation
 *     always returns -1, as the broadcast socket is write-only and cannot be
 *     read.
 */
static ssize_t __guac_socket_broadcast_read_handler(guac_socket* socket,
        void* buf, size_t count) {

    /* Broadcast socket reads are not allowed */
    return -1;

}

/**
 * Callback invoked by guac_client_foreach_user() which write a given chunk of
 * data to that user's socket. If the write attempt fails, the user is
 * signalled to stop with guac_user_stop().
 *
 * @param user
 *     The user that the chunk of data should be written to.
 *
 * @param data
 *     A pointer to a __write_chunk which describes the data to be written.
 *
 * @return
 *     Always NULL.
 */
static void* __write_chunk_callback(guac_user* user, void* data) {

    __write_chunk* chunk = (__write_chunk*) data;

    /* Attempt write, disconnect on failure */
    if (guac_socket_write(user->socket, chunk->buffer, chunk->length))
        guac_user_stop(user);

    return NULL;

}

/**
 * Socket write handler which operates on each of the sockets of all connected
 * users. This write handler will always succeed, but any failing user-specific
 * writes will invoke guac_user_stop() on the failing user.
 *
 * @param socket
 *     The socket to which the given data must be written.
 *
 * @param buf
 *     The buffer containing the data to write.
 *
 * @param count
 *     The number of bytes to attempt to write from the given buffer.
 *
 * @return
 *     The number of bytes written, or -1 if an error occurs. This handler will
 *     always succeed, and thus will always return the exact number of bytes
 *     specified by count.
 */
static ssize_t __guac_socket_broadcast_write_handler(guac_socket* socket,
        const void* buf, size_t count) {

    guac_socket_broadcast_data* data =
        (guac_socket_broadcast_data*) socket->data;

    /* Build chunk */
    __write_chunk chunk;
    chunk.buffer = buf;
    chunk.length = count;

    /* Broadcast chunk to all users */
    guac_client_foreach_user(data->client, __write_chunk_callback, &chunk);

    return count;

}

/**
 * Callback which is invoked by guac_client_foreach_user() to flush all
 * pending data on the given user's socket. If an error occurs while flushing
 * a user's socket, that user is signalled to stop with guac_user_stop().
 *
 * @param user
 *     The user whose socket should be flushed.
 *
 * @param data
 *     Arbitrary data passed to guac_client_foreach_user(). This is not needed
 *     by this callback, and should be left as NULL.
 *
 * @return
 *     Always NULL.
 */
static void* __flush_callback(guac_user* user, void* data) {

    /* Attempt flush, disconnect on failure */
    if (guac_socket_flush(user->socket))
        guac_user_stop(user);

    return NULL;

}

/**
 * Socket flush handler which operates on each of the sockets of all connected
 * users. This flush handler will always succeed, but any failing user-specific
 * flush will invoke guac_user_stop() on the failing user.
 *
 * @param socket
 *     The broadcast socket to flush.
 *
 * @return
 *     Zero if the flush operation succeeds, non-zero if the operation fails.
 *     This handler will always succeed, and thus will always return zero.
 */
static ssize_t __guac_socket_broadcast_flush_handler(guac_socket* socket) {

    guac_socket_broadcast_data* data =
        (guac_socket_broadcast_data*) socket->data;

    /* Flush all users */
    guac_client_foreach_user(data->client, __flush_callback, NULL);

    return 0;

}

/**
 * Callback which is invoked by guac_client_foreach_user() to lock the given
 * user's socket in preparation for the beginning of a Guacamole protocol
 * instruction.
 *
 * @param user
 *     The user whose socket should be locked.
 *
 * @param data
 *     Arbitrary data passed to guac_client_foreach_user(). This is not needed
 *     by this callback, and should be left as NULL.
 *
 * @return
 *     Always NULL.
 */
static void* __lock_callback(guac_user* user, void* data) {

    /* Lock socket */
    guac_socket_instruction_begin(user->socket);

    return NULL;

}

/**
 * Socket lock handler which acquires the socket locks of all connected users.
 * Socket-level locks are acquired in preparation for the beginning of a new
 * Guacamole instruction to ensure that parallel writes are only interleaved at
 * instruction boundaries.
 *
 * @param socket
 *     The broadcast socket to lock.
 */
static void __guac_socket_broadcast_lock_handler(guac_socket* socket) {

    guac_socket_broadcast_data* data =
        (guac_socket_broadcast_data*) socket->data;

    /* Acquire exclusive access to socket */
    pthread_mutex_lock(&(data->socket_lock));

    /* Lock sockets of all users */
    guac_client_foreach_user(data->client, __lock_callback, NULL);

}

/**
 * Callback which is invoked by guac_client_foreach_user() to unlock the given
 * user's socket at the end of a Guacamole protocol instruction.
 *
 * @param user
 *     The user whose socket should be unlocked.
 *
 * @param data
 *     Arbitrary data passed to guac_client_foreach_user(). This is not needed
 *     by this callback, and should be left as NULL.
 *
 * @return
 *     Always NULL.
 */
static void* __unlock_callback(guac_user* user, void* data) {

    /* Unlock socket */
    guac_socket_instruction_end(user->socket);

    return NULL;

}

/**
 * Socket unlock handler which releases the socket locks of all connected users.
 * Socket-level locks are released after a Guacamole instruction has finished
 * being written.
 *
 * @param socket
 *     The broadcast socket to unlock.
 */
static void __guac_socket_broadcast_unlock_handler(guac_socket* socket) {

    guac_socket_broadcast_data* data =
        (guac_socket_broadcast_data*) socket->data;

    /* Unlock sockets of all users */
    guac_client_foreach_user(data->client, __unlock_callback, NULL);

    /* Relinquish exclusive access to socket */
    pthread_mutex_unlock(&(data->socket_lock));

}

/**
 * Callback which handles select operations on the broadcast socket, waiting
 * for data to become available such that the next read operation will not
 * block. This callback always fails, as the broadcast socket is write-only; it
 * cannot be read.
 *
 * @param socket
 *     The broadcast socket to wait for.
 *
 * @param usec_timeout
 *     The maximum amount of time to wait for data, in microseconds, or -1 to
 *     potentially wait forever.
 *
 * @return
 *     A positive value on success, zero if the timeout elapsed and no data is
 *     available, or a negative value if an error occurs. This implementation
 *     always returns -1, as the broadcast socket is write-only and cannot be
 *     read.
 */
static int __guac_socket_broadcast_select_handler(guac_socket* socket,
        int usec_timeout) {

    /* Selecting the broadcast socket is not possible */
    return -1;

}

/**
 * Frees all implementation-specific data associated with the given socket, but
 * not the socket object itself.
 *
 * @param socket
 *     The guac_socket whose associated data should be freed.
 *
 * @return
 *     Zero if the data was successfully freed, non-zero otherwise. This
 *     implementation always succeeds, and will always return zero.
 */
static int __guac_socket_broadcast_free_handler(guac_socket* socket) {

    guac_socket_broadcast_data* data =
        (guac_socket_broadcast_data*) socket->data;

    /* Destroy locks */
    pthread_mutex_destroy(&(data->socket_lock));

    free(data);
    return 0;

}

guac_socket* guac_socket_broadcast(guac_client* client) {

    pthread_mutexattr_t lock_attributes;

    /* Allocate socket and associated data */
    guac_socket* socket = guac_socket_alloc();
    guac_socket_broadcast_data* data =
        malloc(sizeof(guac_socket_broadcast_data));

    /* Store client as socket data */
    data->client = client;
    socket->data = data;

    pthread_mutexattr_init(&lock_attributes);
    pthread_mutexattr_setpshared(&lock_attributes, PTHREAD_PROCESS_SHARED);

    /* Init lock */
    pthread_mutex_init(&(data->socket_lock), &lock_attributes);
    
    /* Set read/write handlers */
    socket->read_handler   = __guac_socket_broadcast_read_handler;
    socket->write_handler  = __guac_socket_broadcast_write_handler;
    socket->select_handler = __guac_socket_broadcast_select_handler;
    socket->flush_handler  = __guac_socket_broadcast_flush_handler;
    socket->lock_handler   = __guac_socket_broadcast_lock_handler;
    socket->unlock_handler = __guac_socket_broadcast_unlock_handler;
    socket->free_handler   = __guac_socket_broadcast_free_handler;

    return socket;

}

