/*
 * 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 "client.h"
#include "common/recording.h"
#include "io.h"
#include "kubernetes.h"
#include "ssl.h"
#include "terminal/terminal.h"
#include "url.h"

#include <guacamole/client.h>
#include <guacamole/protocol.h>
#include <libwebsockets.h>

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

/**
 * Callback invoked by libwebsockets for events related to a WebSocket being
 * used for communicating with an attached Kubernetes pod.
 *
 * @param wsi
 *     The libwebsockets handle for the WebSocket connection.
 *
 * @param reason
 *     The reason (event) that this callback was invoked.
 *
 * @param user
 *     Arbitrary data assocated with the WebSocket session. In some cases,
 *     this is actually event-specific data (such as the
 *     LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERT event).
 *
 * @param in
 *     A pointer to arbitrary, reason-specific data.
 *
 * @param length
 *     An arbitrary, reason-specific length value.
 *
 * @return
 *     An undocumented integer value related the success of handling the
 *     event, or -1 if the WebSocket connection should be closed.
 */
static int guac_kubernetes_lws_callback(struct lws* wsi,
        enum lws_callback_reasons reason, void* user,
        void* in, size_t length) {

    guac_client* client = guac_kubernetes_lws_current_client;

    /* Do not handle any further events if connection is closing */
    if (client->state != GUAC_CLIENT_RUNNING) {
#ifdef HAVE_LWS_CALLBACK_HTTP_DUMMY
        return lws_callback_http_dummy(wsi, reason, user, in, length);
#else
        return 0;
#endif
    }

    switch (reason) {

        /* Complete initialization of SSL */
        case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS:
            guac_kubernetes_init_ssl(client, (SSL_CTX*) user);
            break;

        /* Failed to connect */
        case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
            guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_NOT_FOUND,
                    "Error connecting to Kubernetes server: %s",
                    in != NULL ? (char*) in : "(no error description "
                    "available)");
            break;

        /* Connected / logged in */
        case LWS_CALLBACK_CLIENT_ESTABLISHED:
            guac_client_log(client, GUAC_LOG_INFO,
                    "Kubernetes connection successful.");

            /* Schedule check for pending messages in case messages were added
             * to the outbound message buffer prior to the connection being
             * fully established */
            lws_callback_on_writable(wsi);
            break;

        /* Data received via WebSocket */
        case LWS_CALLBACK_CLIENT_RECEIVE:
            guac_kubernetes_receive_data(client, (const char*) in, length);
            break;

        /* WebSocket is ready for writing */
        case LWS_CALLBACK_CLIENT_WRITEABLE:

            /* Send any pending messages, requesting another callback if
             * yet more messages remain */
            if (guac_kubernetes_write_pending_message(client))
                lws_callback_on_writable(wsi);
            break;

#ifdef HAVE_LWS_CALLBACK_CLIENT_CLOSED
        /* Connection closed (client-specific) */
        case LWS_CALLBACK_CLIENT_CLOSED:
#endif

        /* Connection closed */
        case LWS_CALLBACK_WSI_DESTROY:
        case LWS_CALLBACK_CLOSED:
            guac_client_stop(client);
            guac_client_log(client, GUAC_LOG_DEBUG, "WebSocket connection to "
                    "Kubernetes server closed.");
            break;

        /* No other event types are applicable */
        default:
            break;

    }

#ifdef HAVE_LWS_CALLBACK_HTTP_DUMMY
    return lws_callback_http_dummy(wsi, reason, user, in, length);
#else
    return 0;
#endif

}

/**
 * List of all WebSocket protocols which should be declared as supported by
 * libwebsockets during the initial WebSocket handshake, along with
 * corresponding event-handling callbacks.
 */
struct lws_protocols guac_kubernetes_lws_protocols[] = {
    {
        .name = GUAC_KUBERNETES_LWS_PROTOCOL,
        .callback = guac_kubernetes_lws_callback
    },
    { 0 }
};

/**
 * Input thread, started by the main Kubernetes client thread. This thread
 * continuously reads from the terminal's STDIN and transfers all read
 * data to the Kubernetes connection.
 *
 * @param data
 *     The current guac_client instance.
 *
 * @return
 *     Always NULL.
 */
static void* guac_kubernetes_input_thread(void* data) {

    guac_client* client = (guac_client*) data;
    guac_kubernetes_client* kubernetes_client =
        (guac_kubernetes_client*) client->data;

    char buffer[GUAC_KUBERNETES_MAX_MESSAGE_SIZE];
    int bytes_read;

    /* Write all data read */
    while ((bytes_read = guac_terminal_read_stdin(kubernetes_client->term, buffer, sizeof(buffer))) > 0) {

        /* Send received data to Kubernetes along STDIN channel */
        guac_kubernetes_send_message(client, GUAC_KUBERNETES_CHANNEL_STDIN,
                buffer, bytes_read);

    }

    return NULL;

}

void* guac_kubernetes_client_thread(void* data) {

    guac_client* client = (guac_client*) data;
    guac_kubernetes_client* kubernetes_client =
        (guac_kubernetes_client*) client->data;

    guac_kubernetes_settings* settings = kubernetes_client->settings;

    pthread_t input_thread;
    char endpoint_path[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH];

    /* Verify that the pod name was specified (it's always required) */
    if (settings->kubernetes_pod == NULL) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
                "The name of the Kubernetes pod is a required parameter.");
        goto fail;
    }

    /* Generate endpoint for attachment URL */
    if (guac_kubernetes_endpoint_attach(endpoint_path, sizeof(endpoint_path),
                settings->kubernetes_namespace,
                settings->kubernetes_pod,
                settings->kubernetes_container)) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
                "Unable to generate path for Kubernetes API endpoint: "
                "Resulting path too long");
        goto fail;
    }

    guac_client_log(client, GUAC_LOG_DEBUG, "The endpoint for attaching to "
            "the requested Kubernetes pod is \"%s\".", endpoint_path);

    /* Set up screen recording, if requested */
    if (settings->recording_path != NULL) {
        kubernetes_client->recording = guac_common_recording_create(client,
                settings->recording_path,
                settings->recording_name,
                settings->create_recording_path,
                !settings->recording_exclude_output,
                !settings->recording_exclude_mouse,
                settings->recording_include_keys);
    }

    /* Create terminal */
    kubernetes_client->term = guac_terminal_create(client,
            kubernetes_client->clipboard,
            settings->max_scrollback, settings->font_name, settings->font_size,
            settings->resolution, settings->width, settings->height,
            settings->color_scheme, settings->backspace);

    /* Fail if terminal init failed */
    if (kubernetes_client->term == NULL) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
                "Terminal initialization failed");
        goto fail;
    }

    /* Set up typescript, if requested */
    if (settings->typescript_path != NULL) {
        guac_terminal_create_typescript(kubernetes_client->term,
                settings->typescript_path,
                settings->typescript_name,
                settings->create_typescript_path);
    }

    /* Init libwebsockets context creation parameters */
    struct lws_context_creation_info context_info = {
        .port = CONTEXT_PORT_NO_LISTEN, /* We are not a WebSocket server */
        .uid = -1,
        .gid = -1,
        .protocols = guac_kubernetes_lws_protocols,
        .user = client
    };

    /* Init WebSocket connection parameters which do not vary by Guacmaole
     * connection parameters or creation of future libwebsockets objects */
    struct lws_client_connect_info connection_info = {
        .host = settings->hostname,
        .address = settings->hostname,
        .origin = settings->hostname,
        .port = settings->port,
        .protocol = GUAC_KUBERNETES_LWS_PROTOCOL,
        .userdata = client
    };

    /* If requested, use an SSL/TLS connection for communication with
     * Kubernetes. Note that we disable hostname checks here because we
     * do our own validation - libwebsockets does not validate properly if
     * IP addresses are used. */
    if (settings->use_ssl) {
#ifdef HAVE_LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT
        context_info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
#endif
#ifdef HAVE_LCCSCF_USE_SSL
        connection_info.ssl_connection = LCCSCF_USE_SSL
            | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK;
#else
        connection_info.ssl_connection = 2; /* SSL + no hostname check */
#endif
    }

    /* Create libwebsockets context */
    kubernetes_client->context = lws_create_context(&context_info);
    if (!kubernetes_client->context) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
                "Initialization of libwebsockets failed");
        goto fail;
    }

    /* Generate path dynamically */
    connection_info.context = kubernetes_client->context;
    connection_info.path = endpoint_path;

    /* Open WebSocket connection to Kubernetes */
    kubernetes_client->wsi = lws_client_connect_via_info(&connection_info);
    if (kubernetes_client->wsi == NULL) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
                "Connection via libwebsockets failed");
        goto fail;
    }

    /* Init outbound message buffer */
    pthread_mutex_init(&(kubernetes_client->outbound_message_lock), NULL);

    /* Start input thread */
    if (pthread_create(&(input_thread), NULL, guac_kubernetes_input_thread, (void*) client)) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start input thread");
        goto fail;
    }

    /* Force a redraw of the attached display (there will be no content
     * otherwise, given the stream nature of attaching to a running
     * container) */
    guac_kubernetes_force_redraw(client);

    /* As long as client is connected, continue polling libwebsockets */
    while (client->state == GUAC_CLIENT_RUNNING) {

        /* Cease polling libwebsockets if an error condition is signalled */
        if (lws_service(kubernetes_client->context,
                    GUAC_KUBERNETES_SERVICE_INTERVAL) < 0)
            break;

    }

    /* Kill client and Wait for input thread to die */
    guac_terminal_stop(kubernetes_client->term);
    guac_client_stop(client);
    pthread_join(input_thread, NULL);

fail:

    /* Kill and free terminal, if allocated */
    if (kubernetes_client->term != NULL)
        guac_terminal_free(kubernetes_client->term);

    /* Clean up recording, if in progress */
    if (kubernetes_client->recording != NULL)
        guac_common_recording_free(kubernetes_client->recording);

    /* Free WebSocket context if successfully allocated */
    if (kubernetes_client->context != NULL)
        lws_context_destroy(kubernetes_client->context);

    guac_client_log(client, GUAC_LOG_INFO, "Kubernetes connection ended.");
    return NULL;

}

void guac_kubernetes_resize(guac_client* client, int rows, int columns) {

    char buffer[64];

    guac_kubernetes_client* kubernetes_client =
        (guac_kubernetes_client*) client->data;

    /* Send request only if different from last request */
    if (kubernetes_client->rows != rows ||
            kubernetes_client->columns != columns) {

        kubernetes_client->rows = rows;
        kubernetes_client->columns = columns;

        /* Construct terminal resize message for Kubernetes */
        int length = snprintf(buffer, sizeof(buffer),
                "{\"Width\":%i,\"Height\":%i}", columns, rows);

        /* Schedule message for sending */
        guac_kubernetes_send_message(client, GUAC_KUBERNETES_CHANNEL_RESIZE,
                buffer, length);

    }

}

void guac_kubernetes_force_redraw(guac_client* client) {

    guac_kubernetes_client* kubernetes_client =
        (guac_kubernetes_client*) client->data;

    /* Get current terminal dimensions */
    guac_terminal* term = kubernetes_client->term;
    int rows = term->term_height;
    int columns = term->term_width;

    /* Force a redraw by increasing the terminal size by one character in
     * each dimension and then resizing it back to normal (the same technique
     * used by kubectl */
    guac_kubernetes_resize(client, rows + 1, columns + 1);
    guac_kubernetes_resize(client, rows, columns);

}

