/*
 * 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 "print-job.h"

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

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

/**
 * The command to run when filtering postscript to produce PDF. This must be
 * a NULL-terminated array of arguments, where the first argument is the name
 * of the file to run.
 */
char* const guac_rdp_pdf_filter_command[] = {
    "gs",
    "-q",
    "-dNOPAUSE",
    "-dBATCH",
    "-dSAFER",
    "-dPARANOIDSAFER",
    "-sDEVICE=pdfwrite",
    "-sOutputFile=-",
    "-c",
    ".setpdfwrite",
    "-sstdout=/dev/null",
    "-f",
    "-",
    NULL
};

/**
 * Updates the state of the given print job. Any threads currently blocked by a
 * call to guac_rdp_print_job_wait_for_ack() will be unblocked.
 *
 * @param job
 *     The print job whose state should be updated.
 *
 * @param state
 *     The new state to assign to the given print job.
 */
static void guac_rdp_print_job_set_state(guac_rdp_print_job* job,
        guac_rdp_print_job_state state) {

    pthread_mutex_lock(&(job->state_lock));

    /* Update stream state, signalling modification */
    job->state = state;
    pthread_cond_signal(&(job->state_modified));

    pthread_mutex_unlock(&(job->state_lock));

}

/**
 * Suspends execution of the current thread until the state of the given print
 * job is not GUAC_RDP_PRINT_JOB_WAITING_FOR_ACK. If the state of the print
 * job is GUAC_RDP_PRINT_JOB_ACK_RECEIVED, the state is automatically reset
 * back to GUAC_RDP_PRINT_JOB_WAITING_FOR_ACK prior to returning.
 *
 * @param job
 *     The print job to wait for.
 *
 * @return
 *     Zero if the state of the print job is GUAC_RDP_PRINT_JOB_CLOSED,
 *     non-zero if the state was GUAC_RDP_PRINT_JOB_ACK_RECEIVED and has been
 *     automatically reset to GUAC_RDP_PRINT_JOB_WAITING_FOR_ACK.
 */
static int guac_rdp_print_job_wait_for_ack(guac_rdp_print_job* job) {

    /* Wait for ack if stream open and not yet received */
    pthread_mutex_lock(&(job->state_lock));
    if (job->state == GUAC_RDP_PRINT_JOB_WAITING_FOR_ACK)
        pthread_cond_wait(&job->state_modified, &job->state_lock);

    /* Reset state if ack received */
    int got_ack = (job->state == GUAC_RDP_PRINT_JOB_ACK_RECEIVED);
    if (got_ack)
        job->state = GUAC_RDP_PRINT_JOB_WAITING_FOR_ACK;

    /* Return whether ack was successfully received */
    pthread_mutex_unlock(&(job->state_lock));
    return got_ack;

}

/**
 * Sends a "file" instruction to the given user describing the PDF file that
 * will be sent using the output of the given print job. If the given user no
 * longer exists, the print stream will be automatically terminated.
 *
 * @param user
 *     The user receiving the "file" instruction.
 *
 * @param data
 *     A pointer to the guac_rdp_print_job representing the print job being
 *     streamed.
 *
 * @return
 *     Always NULL.
 */
static void* guac_rdp_print_job_begin_stream(guac_user* user, void* data) {

    guac_rdp_print_job* job = (guac_rdp_print_job*) data;
    guac_client_log(job->client, GUAC_LOG_DEBUG, "Beginning print stream: %s",
            job->filename);

    /* Kill job and do nothing if user no longer exists */
    if (user == NULL) {
        guac_rdp_print_job_kill(job);
        return NULL;
    }

    /* Send document as a PDF file stream */
    guac_protocol_send_file(user->socket, job->stream,
            "application/pdf", job->filename);

    guac_socket_flush(user->socket);
    return NULL;

}

/**
 * Sends a "blob" instruction to the given user containing the provided data
 * along the stream associated with the provided print job. If the given user
 * no longer exists, the print stream will be automatically terminated.
 *
 * @param user
 *     The user receiving the "blob" instruction.
 *
 * @param data
 *     A pointer to an guac_rdp_print_blob structure containing the data to
 *     be written, the number of bytes being written, and the print job being
 *     streamed.
 *
 * @return
 *     Always NULL.
 */
static void* guac_rdp_print_job_send_blob(guac_user* user, void* data) {

    guac_rdp_print_blob* blob = (guac_rdp_print_blob*) data;
    guac_rdp_print_job* job = blob->job;

    guac_client_log(job->client, GUAC_LOG_DEBUG, "Sending %i byte(s) "
            "of filtered output.", blob->length);

    /* Kill job and do nothing if user no longer exists */
    if (user == NULL) {
        guac_rdp_print_job_kill(job);
        return NULL;
    }

    /* Send single blob of print data */
    guac_protocol_send_blob(user->socket, job->stream,
            blob->buffer, blob->length);

    guac_socket_flush(user->socket);
    return NULL;

}

/**
 * Sends an "end" instruction to the given user, closing the stream associated
 * with the given print job. If the given user no longer exists, the print
 * stream will be automatically terminated.
 *
 * @param user
 *     The user receiving the "end" instruction.
 *
 * @param data
 *     A pointer to the guac_rdp_print_job representing the print job being
 *     streamed.
 *
 * @return
 *     Always NULL.
 */
static void* guac_rdp_print_job_end_stream(guac_user* user, void* data) {

    guac_rdp_print_job* job = (guac_rdp_print_job*) data;
    guac_client_log(job->client, GUAC_LOG_DEBUG, "End of print stream.");

    /* Kill job and do nothing if user no longer exists */
    if (user == NULL) {
        guac_rdp_print_job_kill(job);
        return NULL;
    }

    /* Explicitly close down stream */
    guac_protocol_send_end(user->socket, job->stream);
    guac_socket_flush(user->socket);

    /* Clean up our end of the stream */
    guac_user_free_stream(job->user, job->stream);

    return NULL;

}

/**
 * Handler for "ack" messages received in response to printed data. Additional
 * data will be sent as a result or, if no data remains, the stream will be
 * terminated. It is required that the data pointer of the provided stream be
 * set to the file descriptor from which the printed data should be read.
 *
 * @param user
 *     The user to whom the printed data is being sent.
 *
 * @param stream
 *     The stream along which the printed data is to be sent. The data pointer
 *     of this stream MUST be set to the file descriptor from which the data
 *     being sent is to be read.
 *
 * @param message
 *     An arbitrary, human-readable message describing the success/failure of
 *     the operation being acknowledged (either stream creation or receipt of
 *     a blob).
 *
 * @param status
 *     The status code describing the success/failure of the operation being
 *     acknowledged (either stream creation or receipt of a blob).
 *
 * @return
 *     Always zero.
 */
static int guac_rdp_print_filter_ack_handler(guac_user* user,
        guac_stream* stream, char* message, guac_protocol_status status) {

    guac_rdp_print_job* job = (guac_rdp_print_job*) stream->data;

    /* Update state for successful acks */
    if (status == GUAC_PROTOCOL_STATUS_SUCCESS)
        guac_rdp_print_job_set_state(job, GUAC_RDP_PRINT_JOB_ACK_RECEIVED);

    /* Terminate stream if ack signals an error */
    else {

        /* Note that the stream was aborted by the user */
        guac_client_log(job->client, GUAC_LOG_INFO, "User explicitly aborted "
                "print stream.");

        /* Kill job (the results will no longer be received) */
        guac_rdp_print_job_kill(job);

    }

    return 0;

}

/**
 * Forks a new print filtering process which accepts PostScript input and
 * produces PDF output. File descriptors for writing input and reading output
 * will automatically be allocated and must be manually closed when processing
 * is complete.
 *
 * @param client
 *     The guac_client associated with the print job for which this filter
 *     process is being created.
 *
 * @param input_fd
 *     A pointer to an int which should receive the input file descriptor of
 *     the filter process. PostScript input for the filter process should be
 *     written to this file descriptor.
 *
 * @param output_fd
 *     A pointer to an int which should receive the output file descriptor of
 *     the filter process. PDF output from the filter process must be
 *     continuously read from this file descriptor or the pipeline may block.
 *
 * @return
 *     The PID of the filter process, or -1 if the filter process could not be
 *     created. If the filter process could not be created, the values assigned
 *     through input_fd and output_fd are undefined.
 */
static pid_t guac_rdp_create_filter_process(guac_client* client,
        int* input_fd, int* output_fd) {

    int child_pid;
    int stdin_pipe[2];
    int stdout_pipe[2];

    /* Create STDIN pipe */
    if (pipe(stdin_pipe)) {
        guac_client_log(client, GUAC_LOG_ERROR, "Unable to create STDIN "
                "pipe for PDF filter process: %s", strerror(errno));
        return -1;
    }

    /* Create STDOUT pipe */
    if (pipe(stdout_pipe)) {
        guac_client_log(client, GUAC_LOG_ERROR, "Unable to create STDOUT "
                "pipe for PDF filter process: %s", strerror(errno));
        close(stdin_pipe[0]);
        close(stdin_pipe[1]);
        return -1;
    }

    /* Store parent side of stdin/stdout */
    *input_fd = stdin_pipe[1];
    *output_fd = stdout_pipe[0];

    /* Fork child process */
    child_pid = fork();

    /* Log fork errors */
    if (child_pid == -1) {
        guac_client_log(client, GUAC_LOG_ERROR, "Unable to fork PDF filter "
                "process: %s", strerror(errno));
        close(stdin_pipe[0]);
        close(stdin_pipe[1]);
        close(stdout_pipe[0]);
        close(stdout_pipe[1]);
        return -1;
    }

    /* Child process */
    if (child_pid == 0) {

        /* Close unneeded ends of pipe */
        close(stdin_pipe[1]);
        close(stdout_pipe[0]);

        /* Reassign file descriptors as STDIN/STDOUT */
        dup2(stdin_pipe[0], STDIN_FILENO);
        dup2(stdout_pipe[1], STDOUT_FILENO);

        /* Run PDF filter */
        guac_client_log(client, GUAC_LOG_INFO, "Running %s",
                guac_rdp_pdf_filter_command[0]);
        if (execvp(guac_rdp_pdf_filter_command[0],
                    guac_rdp_pdf_filter_command) < 0)
            guac_client_log(client, GUAC_LOG_ERROR, "Unable to execute PDF "
                    "filter command: %s", strerror(errno));
        else
            guac_client_log(client, GUAC_LOG_ERROR, "Unable to execute PDF "
                    "filter command, but no error given");

        /* Terminate child process */
        exit(1);

    }

    /* Log fork success */
    guac_client_log(client, GUAC_LOG_INFO, "Created PDF filter process "
            "PID=%i", child_pid);

    /* Close unneeded ends of pipe */
    close(stdin_pipe[0]);
    close(stdout_pipe[1]);
    return child_pid;

}

/**
 * Thread which continuously reads from the output file descriptor associated
 * with the given print job, writing filtered PDF output to the associated
 * Guacamole stream, and terminating only after the print job has completed
 * processing or the associated Guacamole stream has closed.
 *
 * @param data
 *     A pointer to the guac_rdp_print_job representing the print job that
 *     should be read.
 *
 * @return
 *     Always NULL.
 */
static void* guac_rdp_print_job_output_thread(void* data) {

    int length;
    char buffer[6048];

    guac_rdp_print_job* job = (guac_rdp_print_job*) data;
    guac_client_log(job->client, GUAC_LOG_DEBUG, "Reading output from filter "
            "process...");

    /* Read continuously while data remains */
    while ((length = read(job->output_fd, buffer, sizeof(buffer))) > 0) {

        /* Wait for client to be ready for blob */
        if (guac_rdp_print_job_wait_for_ack(job)) {

            guac_rdp_print_blob blob = {
                .job    = job,
                .buffer = buffer,
                .length = length
            };

            /* Write a single blob of output */
            guac_client_for_user(job->client, job->user,
                    guac_rdp_print_job_send_blob, &blob);

        }

        /* Abort if stream is closed */
        else {
            guac_client_log(job->client, GUAC_LOG_DEBUG, "Print stream "
                    "explicitly aborted.");
            break;
        }

    }

    /* Warn of read errors */
    if (length < 0)
        guac_client_log(job->client, GUAC_LOG_ERROR,
                "Error reading from filter: %s", strerror(errno));

    /* Terminate stream */
    guac_client_for_user(job->client, job->user,
            guac_rdp_print_job_end_stream, job);

    /* Ensure all associated file descriptors are closed */
    close(job->input_fd);
    close(job->output_fd);

    guac_client_log(job->client, GUAC_LOG_DEBUG, "Print job completed.");
    return NULL;

}

void* guac_rdp_print_job_alloc(guac_user* user, void* data) {

    /* Allocate nothing if user does not exist */
    if (user == NULL)
        return NULL;

    /* Allocate stream for print job output */
    guac_stream* stream = guac_user_alloc_stream(user);
    if (stream == NULL)
        return NULL;

    /* Bail early if allocation fails */
    guac_rdp_print_job* job = malloc(sizeof(guac_rdp_print_job));
    if (job == NULL)
        return NULL;

    /* Associate job with stream and dependent data */
    job->client = user->client;
    job->user = user;
    job->stream = stream;
    job->bytes_received = 0;

    /* Set default filename for job */
    strcpy(job->filename, GUAC_RDP_PRINT_JOB_DEFAULT_FILENAME);

    /* Prepare stream for receipt of acks */
    stream->ack_handler = guac_rdp_print_filter_ack_handler;
    stream->data = job;

    /* Create print filter process */
    job->filter_pid = guac_rdp_create_filter_process(job->client,
            &job->input_fd, &job->output_fd);

    /* Abort if print filter process cannot be created */
    if (job->filter_pid == -1) {
        guac_user_free_stream(user, stream);
        free(job);
        return NULL;
    }

    /* Init stream state signal and lock */
    job->state = GUAC_RDP_PRINT_JOB_WAITING_FOR_ACK;
    pthread_cond_init(&job->state_modified, NULL);
    pthread_mutex_init(&job->state_lock, NULL);

    /* Start output thread */
    pthread_create(&job->output_thread, NULL,
            guac_rdp_print_job_output_thread, job);

    /* Print job allocated successfully */
    return job;

}

/**
 * Attempts to parse the given PostScript "%%Title:" header, storing the
 * contents within the filename of the given print job. If the given buffer
 * does not immediately begin with the "%%Title:" header, this function has no
 * effect.
 *
 * @param job
 *     The job whose filename should be set if the "%%Title:" header is
 *     successfully parsed.
 *
 * @param buffer
 *     The buffer to parse as the "%%Title:" header.
 *
 * @param length
 *     The number of bytes within the buffer.
 *
 * @return
 *     Non-zero if the given buffer began with the "%%Title:" header and this
 *     header was successfully parsed, zero otherwise.
 */
static int guac_rdp_print_job_parse_title_header(guac_rdp_print_job* job,
        void* buffer, int length) {

    int i;
    char* current = buffer;
    char* filename = job->filename;

    /* Verify that the buffer begins with "%%Title: " */
    if (strncmp(current, "%%Title: ", 9) != 0)
        return 0;

    /* Skip past "%%Title: " */
    current += 9;
    length -= 9;

    /* Calculate space remaining in filename */
    int remaining = sizeof(job->filename) - 5 /* ".pdf\0" */;

    /* Do not exceed bounds of provided buffer */
    if (length < remaining)
        remaining = length;

    /* Copy as much of title as reasonable */
    for (i = 0; i < remaining; i++) {

        /* Get character, stop at EOL */
        char c = *(current++);
        if (c == '\r' || c == '\n')
            break;

        /* Copy to filename */
        *(filename++) = c;

    }

    /* Append extension to filename */
    strcpy(filename, ".pdf");

    /* Title successfully parsed */
    return 1;

}

/**
 * Searches through the given buffer for PostScript headers denoting the title
 * of the document, assigning the filename of the given print job using the
 * discovered title. If no title can be found within
 * GUAC_RDP_PRINT_JOB_TITLE_SEARCH_LENGTH bytes, this function has no effect.
 *
 * @param job
 *     The job whose filename should be set if the document title can be found
 *     within the given buffer.
 *
 * @param buffer
 *     The buffer to search for the document title.
 *
 * @param length
 *     The number of bytes within the buffer.
 */
static void guac_rdp_print_job_read_filename(guac_rdp_print_job* job,
        void* buffer, int length) {

    char* current = buffer;
    int i;

    /* Restrict search area */
    if (length > GUAC_RDP_PRINT_JOB_TITLE_SEARCH_LENGTH)
        length = GUAC_RDP_PRINT_JOB_TITLE_SEARCH_LENGTH;

    /* Search for document title within buffer */
    for (i = 0; i < length; i++) {

        /* If document title has been found, we're done */
        if (guac_rdp_print_job_parse_title_header(job, current, length))
            break;

        /* Advance to next character */
        length--;
        current++;

    }

}

int guac_rdp_print_job_write(guac_rdp_print_job* job,
        void* buffer, int length) {

    /* Create print job, if not yet created */
    if (job->bytes_received == 0) {

        /* Attempt to read document title from first buffer of data */
        guac_rdp_print_job_read_filename(job, buffer, length);

        /* Begin print stream */
        guac_client_for_user(job->client, job->user,
                guac_rdp_print_job_begin_stream, job);

    }

    /* Update counter of bytes received */
    job->bytes_received += length;

    /* Write data to filter process */
    return write(job->input_fd, buffer, length);

}

void guac_rdp_print_job_free(guac_rdp_print_job* job) {

    /* No more input will be provided */
    close(job->input_fd);

    /* Wait for job to terminate */
    pthread_join(job->output_thread, NULL);

    /* Free base structure */
    free(job);

}

void guac_rdp_print_job_kill(guac_rdp_print_job* job) {

    /* Stop all handling of I/O */
    close(job->input_fd);
    close(job->output_fd);

    /* Mark stream as closed */
    guac_rdp_print_job_set_state(job, GUAC_RDP_PRINT_JOB_CLOSED);

}

