/*
 * 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 "terminal/common.h"
#include "terminal/terminal.h"

#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/user.h>

/**
 * Handler for "blob" instructions which writes the data of received
 * blobs to STDIN of the terminal associated with the stream.
 *
 * @see guac_user_blob_handler
 */
static int guac_terminal_input_stream_blob_handler(guac_user* user,
        guac_stream* stream, void* data, int length) {

    guac_terminal* term = (guac_terminal*) stream->data;

    /* Attempt to write received data */
    guac_terminal_lock(term);
    int result = guac_terminal_write_all(term->stdin_pipe_fd[1], data, length);
    guac_terminal_unlock(term);

    /* Acknowledge receipt of data and result of write attempt */
    if (result <= 0) {

        guac_user_log(user, GUAC_LOG_DEBUG,
                "Attempt to write to STDIN via an inbound stream failed.");

        guac_protocol_send_ack(user->socket, stream,
                "Attempt to write to STDIN failed.",
                GUAC_PROTOCOL_STATUS_SUCCESS);

    }
    else {

        guac_user_log(user, GUAC_LOG_DEBUG,
                "%i bytes successfully written to STDIN from an inbound stream.",
                length);

        guac_protocol_send_ack(user->socket, stream,
                "Data written to STDIN.",
                GUAC_PROTOCOL_STATUS_SUCCESS);

    }

    guac_socket_flush(user->socket);
    return 0;

}

/**
 * Handler for "end" instructions which disassociates the given
 * stream from the terminal, allowing user input to resume.
 *
 * @see guac_user_end_handler
 */
static int guac_terminal_input_stream_end_handler(guac_user* user,
        guac_stream* stream) {

    guac_terminal* term = (guac_terminal*) stream->data;

    /* Reset input stream, unblocking user input */
    guac_terminal_lock(term);
    term->input_stream = NULL;
    guac_terminal_unlock(term);

    guac_user_log(user, GUAC_LOG_DEBUG, "Inbound stream closed. User input "
            "will now resume affecting STDIN.");

    return 0;

}

/**
 * Internal implementation of guac_terminal_send_stream() which assumes
 * that the guac_terminal has already been locked through a call to
 * guac_terminal_lock(). The semantics of all parameters and the return
 * value are identical to guac_terminal_send_stream().
 *
 * @see guac_terminal_send_stream()
 */
static int __guac_terminal_send_stream(guac_terminal* term, guac_user* user,
        guac_stream* stream) {

    /* Deny redirecting STDIN if terminal is not started */
    if (!term->started) {

        guac_user_log(user, GUAC_LOG_DEBUG, "Attempt to direct the contents "
                "of an inbound stream to STDIN denied. The terminal is not "
                "yet ready for input.");

        guac_protocol_send_ack(user->socket, stream,
                "Terminal not yet started.",
                GUAC_PROTOCOL_STATUS_RESOURCE_CONFLICT);

        guac_socket_flush(user->socket);
        return 1;

    }

    /* If a stream is already being used for STDIN, deny creation of
     * further streams */
    if (term->input_stream != NULL) {

        guac_user_log(user, GUAC_LOG_DEBUG, "Attempt to direct the contents "
                "of an inbound stream to STDIN denied. STDIN is already "
                "being read from an inbound stream.");

        guac_protocol_send_ack(user->socket, stream,
                "STDIN is already being read from a stream.",
                GUAC_PROTOCOL_STATUS_RESOURCE_CONFLICT);

        guac_socket_flush(user->socket);
        return 1;

    }

    guac_user_log(user, GUAC_LOG_DEBUG, "Now reading STDIN from inbound "
            "stream. User input will no longer affect STDIN until the "
            "stream is closed.");

    stream->blob_handler = guac_terminal_input_stream_blob_handler;
    stream->end_handler = guac_terminal_input_stream_end_handler;
    stream->data = term;

    /* Block user input until stream is ended */
    term->input_stream = stream;

    /* Acknowledge redirection from stream */
    guac_protocol_send_ack(user->socket, stream,
            "Now reading STDIN from stream.",
            GUAC_PROTOCOL_STATUS_SUCCESS);

    guac_socket_flush(user->socket);
    return 0;

}

int guac_terminal_send_stream(guac_terminal* term, guac_user* user,
        guac_stream* stream) {

    int result;

    guac_terminal_lock(term);
    result = __guac_terminal_send_stream(term, user, stream);
    guac_terminal_unlock(term);

    return result;

}

