/*
 * 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/parser.h"
#include "guacamole/protocol.h"
#include "guacamole/socket.h"
#include "guacamole/user.h"
#include "user-handlers.h"

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

/**
 * Parameters required by the user input thread.
 */
typedef struct guac_user_input_thread_params {

    /**
     * The parser which will be used throughout the user's session.
     */
    guac_parser* parser;

    /**
     * A reference to the connected user.
     */
    guac_user* user;

    /**
     * The number of microseconds to wait for instructions from a connected
     * user before closing the connection with an error.
     */
    int usec_timeout;

} guac_user_input_thread_params;

/**
 * Prints an error message using the logging facilities of the given user,
 * automatically including any information present in guac_error.
 *
 * @param user
 *     The guac_user associated with the error that occurred.
 *
 * @param level
 *     The level at which to log this message.
 *
 * @param message
 *     The message to log.
 */
static void guac_user_log_guac_error(guac_user* user,
        guac_client_log_level level, const char* message) {

    if (guac_error != GUAC_STATUS_SUCCESS) {

        /* If error message provided, include in log */
        if (guac_error_message != NULL)
            guac_user_log(user, level, "%s: %s", message,
                    guac_error_message);

        /* Otherwise just log with standard status string */
        else
            guac_user_log(user, level, "%s: %s", message,
                    guac_status_string(guac_error));

    }

    /* Just log message if no status code */
    else
        guac_user_log(user, level, "%s", message);

}

/**
 * Logs a reasonable explanatory message regarding handshake failure based on
 * the current value of guac_error.
 *
 * @param user
 *     The guac_user associated with the failed Guacamole protocol handshake.
 */
static void guac_user_log_handshake_failure(guac_user* user) {

    if (guac_error == GUAC_STATUS_CLOSED)
        guac_user_log(user, GUAC_LOG_INFO,
                "Guacamole connection closed during handshake");
    else if (guac_error == GUAC_STATUS_PROTOCOL_ERROR)
        guac_user_log(user, GUAC_LOG_ERROR,
                "Guacamole protocol violation. Perhaps the version of "
                "guacamole-client is incompatible with this version of "
                "libguac?");
    else
        guac_user_log(user, GUAC_LOG_WARNING,
                "Guacamole handshake failed: %s",
                guac_status_string(guac_error));

}

/**
 * The thread which handles all user input, calling event handlers for received
 * instructions.
 *
 * @param data
 *     A pointer to a guac_user_input_thread_params structure describing the
 *     user whose input is being handled and the guac_parser with which to
 *     handle it.
 *
 * @return
 *     Always NULL.
 */
static void* guac_user_input_thread(void* data) {

    guac_user_input_thread_params* params =
        (guac_user_input_thread_params*) data;

    int usec_timeout = params->usec_timeout;
    guac_user* user = params->user;
    guac_parser* parser = params->parser;
    guac_client* client = user->client;
    guac_socket* socket = user->socket;

    /* Guacamole user input loop */
    while (client->state == GUAC_CLIENT_RUNNING && user->active) {

        /* Read instruction, stop on error */
        if (guac_parser_read(parser, socket, usec_timeout)) {

            if (guac_error == GUAC_STATUS_TIMEOUT)
                guac_user_abort(user, GUAC_PROTOCOL_STATUS_CLIENT_TIMEOUT, "User is not responding.");

            else {
                if (guac_error != GUAC_STATUS_CLOSED)
                    guac_user_log_guac_error(user, GUAC_LOG_WARNING,
                            "Guacamole connection failure");
                guac_user_stop(user);
            }

            return NULL;
        }

        /* Reset guac_error and guac_error_message (user/client handlers are not
         * guaranteed to set these) */
        guac_error = GUAC_STATUS_SUCCESS;
        guac_error_message = NULL;

        /* Call handler, stop on error */
        if (__guac_user_call_opcode_handler(__guac_instruction_handler_map, 
                user, parser->opcode, parser->argc, parser->argv)) {

            /* Log error */
            guac_user_log_guac_error(user, GUAC_LOG_WARNING,
                    "User connection aborted");

            /* Log handler details */
            guac_user_log(user, GUAC_LOG_DEBUG, "Failing instruction handler in user was \"%s\"", parser->opcode);

            guac_user_stop(user);
            return NULL;
        }

    }

    return NULL;

}

/**
 * Starts the input/output threads of a new user. This function will block
 * until the user disconnects. If an error prevents the input/output threads
 * from starting, guac_user_stop() will be invoked on the given user.
 *
 * @param parser
 *     The guac_parser to use to handle all input from the given user.
 *
 * @param user
 *     The user whose associated I/O transfer threads should be started.
 *
 * @param usec_timeout
 *     The number of microseconds to wait for instructions from the given
 *     user before closing the connection with an error.
 *
 * @return
 *     Zero if the I/O threads started successfully and user has disconnected,
 *     or non-zero if the I/O threads could not be started.
 */
static int guac_user_start(guac_parser* parser, guac_user* user,
        int usec_timeout) {

    guac_user_input_thread_params params = {
        .parser = parser,
        .user = user,
        .usec_timeout = usec_timeout
    };

    pthread_t input_thread;

    if (pthread_create(&input_thread, NULL, guac_user_input_thread, (void*) &params)) {
        guac_user_log(user, GUAC_LOG_ERROR, "Unable to start input thread");
        guac_user_stop(user);
        return -1;
    }

    /* Wait for I/O threads */
    pthread_join(input_thread, NULL);

    /* Explicitly signal disconnect */
    guac_protocol_send_disconnect(user->socket);
    guac_socket_flush(user->socket);

    /* Done */
    return 0;

}

/**
 * This function loops through the received instructions during the handshake
 * with the client attempting to join the connection, and runs the handlers
 * for each of the opcodes, ending when the connect instruction is received.
 * Returns zero if the handshake completes successfully with the connect opcode,
 * or a non-zero value if an error occurs.
 * 
 * @param user
 *     The guac_user attempting to join the connection.
 * 
 * @param parser
 *     The parser used to examine the received data.
 * 
 * @param usec_timeout
 *     The timeout, in microseconds, for reading the instructions.
 * 
 * @return
 *     Zero if the handshake completes successfully with the connect opcode,
 *     or non-zero if an error occurs.
 */
static int __guac_user_handshake(guac_user* user, guac_parser* parser,
        int usec_timeout) {
    
    guac_socket* socket = user->socket;
    
    /* Handle each of the opcodes. */
    while (guac_parser_read(parser, socket, usec_timeout) == 0) {
        
        /* If we receive the connect opcode, we're done. */
        if (strcmp(parser->opcode, "connect") == 0)
            return 0;
        
        guac_user_log(user, GUAC_LOG_DEBUG, "Processing instruction: %s",
                parser->opcode);
        
        /* Run instruction handler for opcode with arguments. */
        if (__guac_user_call_opcode_handler(__guac_handshake_handler_map, user,
                parser->opcode, parser->argc, parser->argv)) {
            
            guac_user_log_handshake_failure(user);
            guac_user_log_guac_error(user, GUAC_LOG_DEBUG,
                    "Error handling instruction during handshake.");
            guac_user_log(user, GUAC_LOG_DEBUG, "Failed opcode: %s",
                    parser->opcode);

            guac_parser_free(parser);
            return 1;
            
        }
        
    }
    
    /* If we get here it's because we never got the connect instruction. */
    guac_user_log(user, GUAC_LOG_ERROR,
            "Handshake failed, \"connect\" instruction was not received.");
    return 1;
}

int guac_user_handle_connection(guac_user* user, int usec_timeout) {

    guac_socket* socket = user->socket;
    guac_client* client = user->client;
    
    user->info.audio_mimetypes = NULL;
    user->info.image_mimetypes = NULL;
    user->info.video_mimetypes = NULL;
    user->info.timezone = NULL;
    
    /* Count number of arguments. */
    int num_args;
    for (num_args = 0; client->args[num_args] != NULL; num_args++);
    
    /* Send args */
    if (guac_protocol_send_args(socket, client->args)
            || guac_socket_flush(socket)) {

        /* Log error */
        guac_user_log_handshake_failure(user);
        guac_user_log_guac_error(user, GUAC_LOG_DEBUG,
                "Error sending \"args\" to new user");

        return 1;
    }

    guac_parser* parser = guac_parser_alloc();

    /* Perform the handshake with the client. */
    if (__guac_user_handshake(user, parser, usec_timeout)) {
        guac_parser_free(parser);
        return 1;
    }

    /* Acknowledge connection availability */
    guac_protocol_send_ready(socket, client->connection_id);
    guac_socket_flush(socket);
    
    /* Verify argument count. */
    if (parser->argc != (num_args + 1)) {
        guac_client_log(client, GUAC_LOG_ERROR, "Client did not return the "
                "expected number of arguments.");
        return 1;
    }
    
    /* Attempt to join user to connection. */
    if (guac_client_add_user(client, user, (parser->argc - 1), parser->argv + 1))
        guac_client_log(client, GUAC_LOG_ERROR, "User \"%s\" could NOT "
                "join connection \"%s\"", user->user_id, client->connection_id);

    /* Begin user connection if join successful */
    else {

        guac_client_log(client, GUAC_LOG_INFO, "User \"%s\" joined connection "
                "\"%s\" (%i users now present)", user->user_id,
                client->connection_id, client->connected_users);
        if (strcmp(parser->argv[0],"") != 0)
            guac_client_log(client, GUAC_LOG_DEBUG, "Client is using protocol "
                    "version \"%s\"", parser->argv[0]);
        else
            guac_client_log(client, GUAC_LOG_DEBUG, "Client has not defined "
                    "its protocol version.");

        /* Handle user I/O, wait for connection to terminate */
        guac_user_start(parser, user, usec_timeout);

        /* Remove/free user */
        guac_client_remove_user(client, user);
        guac_client_log(client, GUAC_LOG_INFO, "User \"%s\" disconnected (%i "
                "users remain)", user->user_id, client->connected_users);

    }
    
    /* Free mimetype character arrays. */
    guac_free_mimetypes((char **) user->info.audio_mimetypes);
    guac_free_mimetypes((char **) user->info.image_mimetypes);
    guac_free_mimetypes((char **) user->info.video_mimetypes);
    
    /* Free timezone info. */
    free((char *) user->info.timezone);
    
    guac_parser_free(parser);

    /* Successful disconnect */
    return 0;

}

