/*
 * 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 "common/recording.h"

#include <guacamole/client.h>
#include <guacamole/socket.h>

#ifdef __MINGW32__
#include <direct.h>
#endif

#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

/**
 * Attempts to open a new recording within the given path and having the given
 * name. If such a file already exists, sequential numeric suffixes (.1, .2,
 * .3, etc.) are appended until a filename is found which does not exist (or
 * until the maximum number of numeric suffixes has been tried). If the file
 * absolutely cannot be opened due to an error, -1 is returned and errno is set
 * appropriately.
 *
 * @param path
 *     The full path to the directory in which the data file should be created.
 *
 * @param name
 *     The name of the data file which should be crated within the given path.
 *
 * @param basename
 *     A buffer in which the path, a path separator, the filename, any
 *     necessary suffix, and a NULL terminator will be stored. If insufficient
 *     space is available, -1 will be returned, and errno will be set to
 *     ENAMETOOLONG.
 *
 * @param basename_size
 *     The number of bytes available within the provided basename buffer.
 *
 * @return
 *     The file descriptor of the open data file if open succeeded, or -1 on
 *     failure.
 */
static int guac_common_recording_open(const char* path,
        const char* name, char* basename, int basename_size) {

    int i;

    /* Concatenate path and name (separated by a single slash) */
    int basename_length = snprintf(basename,
            basename_size - GUAC_COMMON_RECORDING_MAX_SUFFIX_LENGTH,
            "%s/%s", path, name);

    /* Abort if maximum length reached */
    if (basename_length ==
            basename_size - GUAC_COMMON_RECORDING_MAX_SUFFIX_LENGTH) {
        errno = ENAMETOOLONG;
        return -1;
    }

    /* Attempt to open recording */
    int fd = open(basename,
            O_CREAT | O_EXCL | O_WRONLY,
            S_IRUSR | S_IWUSR);

    /* Continuously retry with alternate names on failure */
    if (fd == -1) {

        /* Prepare basename for additional suffix */
        basename[basename_length] = '.';
        char* suffix = &(basename[basename_length + 1]);

        /* Continue retrying alternative suffixes if file already exists */
        for (i = 1; fd == -1 && errno == EEXIST
                && i <= GUAC_COMMON_RECORDING_MAX_SUFFIX; i++) {

            /* Append new suffix */
            sprintf(suffix, "%i", i);

            /* Retry with newly-suffixed filename */
            fd = open(basename,
                    O_CREAT | O_EXCL | O_WRONLY,
                    S_IRUSR | S_IWUSR);

        }

        /* Abort if we've run out of filenames */
        if (fd == -1)
            return -1;

    } /* end if open succeeded */

/* Explicit file locks are required only on POSIX platforms */
#ifndef __MINGW32__
    /* Lock entire output file for writing by the current process */
    struct flock file_lock = {
        .l_type   = F_WRLCK,
        .l_whence = SEEK_SET,
        .l_start  = 0,
        .l_len    = 0,
        .l_pid    = getpid()
    };

    /* Abort if file cannot be locked for reading */
    if (fcntl(fd, F_SETLK, &file_lock) == -1) {
        close(fd);
        return -1;
    }
#endif

    return fd;

}

int guac_common_recording_create(guac_client* client, const char* path,
        const char* name, int create_path) {

    char filename[GUAC_COMMON_RECORDING_MAX_NAME_LENGTH];

    /* Create path if it does not exist, fail if impossible */
#ifndef __MINGW32__
    if (create_path && mkdir(path, S_IRWXU) && errno != EEXIST) {
#else
    if (create_path && _mkdir(path) && errno != EEXIST) {
#endif
        guac_client_log(client, GUAC_LOG_ERROR,
                "Creation of recording failed: %s", strerror(errno));
        return 1;
    }

    /* Attempt to open recording file */
    int fd = guac_common_recording_open(path, name, filename, sizeof(filename));
    if (fd == -1) {
        guac_client_log(client, GUAC_LOG_ERROR,
                "Creation of recording failed: %s", strerror(errno));
        return 1;
    }

    /* Replace client socket with wrapped socket */
    client->socket = guac_socket_tee(client->socket, guac_socket_open(fd));

    /* Recording creation succeeded */
    guac_client_log(client, GUAC_LOG_INFO,
            "Recording of session will be saved to \"%s\".",
            filename);

    return 0;

}

