/*
 * 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 "channels/common-svc.h"
#include "channels/rdpdr/rdpdr-fs-messages-dir-info.h"
#include "channels/rdpdr/rdpdr-fs-messages-file-info.h"
#include "channels/rdpdr/rdpdr-fs-messages-vol-info.h"
#include "channels/rdpdr/rdpdr-fs-messages.h"
#include "channels/rdpdr/rdpdr.h"
#include "download.h"
#include "fs.h"
#include "unicode.h"

#include <freerdp/channels/rdpdr.h>
#include <guacamole/client.h>
#include <winpr/nt.h>
#include <winpr/stream.h>
#include <winpr/wtypes.h>

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

void guac_rdpdr_fs_process_create(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    wStream* output_stream;
    int file_id;

    int desired_access, file_attributes;
    int create_disposition, create_options, path_length;
    char path[GUAC_RDP_FS_MAX_PATH];

    /* Check remaining stream data prior to reading. */
    if (Stream_GetRemainingLength(input_stream) < 32) {
        guac_client_log(svc->client, GUAC_LOG_WARNING, "File stream does not "
                "contain the expected number of bytes. File sharing may not "
                "work as expected.");
        return;
    }
    
    /* Read "create" information */
    Stream_Read_UINT32(input_stream, desired_access);
    Stream_Seek_UINT64(input_stream); /* allocation size */
    Stream_Read_UINT32(input_stream, file_attributes);
    Stream_Seek_UINT32(input_stream); /* shared access */
    Stream_Read_UINT32(input_stream, create_disposition);
    Stream_Read_UINT32(input_stream, create_options);
    Stream_Read_UINT32(input_stream, path_length);

    /* Convert path to UTF-8 */
    guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), path_length/2 - 1,
            path, sizeof(path));

    /* Open file */
    file_id = guac_rdp_fs_open((guac_rdp_fs*) device->data, path,
            desired_access, file_attributes,
            create_disposition, create_options);

    guac_client_log(svc->client, GUAC_LOG_DEBUG,
            "%s: [file_id=%i] "
             "desired_access=0x%x, file_attributes=0x%x, "
             "create_disposition=0x%x, create_options=0x%x, path=\"%s\"",
             __func__, file_id,
             desired_access, file_attributes,
             create_disposition, create_options, path);

    /* If an error occurred, notify server */
    if (file_id < 0) {
        guac_client_log(svc->client, GUAC_LOG_ERROR,
                "File open refused (%i): \"%s\"", file_id, path);

        output_stream = guac_rdpdr_new_io_completion(device,
                iorequest->completion_id, guac_rdp_fs_get_status(file_id), 5);
        Stream_Write_UINT32(output_stream, 0); /* fileId */
        Stream_Write_UINT8(output_stream,  0); /* information */
    }

    /* Otherwise, open succeeded */
    else {

        guac_rdp_fs_file* file;

        output_stream = guac_rdpdr_new_io_completion(device,
                iorequest->completion_id, STATUS_SUCCESS, 5);
        Stream_Write_UINT32(output_stream, file_id);    /* fileId */
        Stream_Write_UINT8(output_stream,  0);          /* information */

        /* Create \Download if it doesn't exist */
        file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, file_id);
        if (file != NULL && strcmp(file->absolute_path, "\\") == 0) {
            int download_id =
                guac_rdp_fs_open((guac_rdp_fs*) device->data, "\\Download",
                    GENERIC_READ, 0, FILE_OPEN_IF, FILE_DIRECTORY_FILE);

            if (download_id >= 0)
                guac_rdp_fs_close((guac_rdp_fs*) device->data, download_id);
        }

    }

    guac_rdp_common_svc_write(svc, output_stream);

}

void guac_rdpdr_fs_process_read(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    UINT32 length;
    UINT64 offset;
    char* buffer;
    int bytes_read;

    wStream* output_stream;

    /* Check remaining bytes before reading stream. */
    if (Stream_GetRemainingLength(input_stream) < 12) {
        guac_client_log(svc->client, GUAC_LOG_WARNING, "File Stream does not "
                "contain the expected number of bytes. File sharing may not "
                "work as expected.");
        return;
    }
    
    /* Read packet */
    Stream_Read_UINT32(input_stream, length);
    Stream_Read_UINT64(input_stream, offset);

    guac_client_log(svc->client, GUAC_LOG_DEBUG,
            "%s: [file_id=%i] length=%i, offset=%" PRIu64,
             __func__, iorequest->file_id, length, (uint64_t) offset);

    /* Ensure buffer size does not exceed a safe maximum */
    if (length > GUAC_RDP_MAX_READ_BUFFER)
        length = GUAC_RDP_MAX_READ_BUFFER;

    /* Allocate buffer */
    buffer = malloc(length);

    /* Attempt read */
    bytes_read = guac_rdp_fs_read((guac_rdp_fs*) device->data,
            iorequest->file_id, offset, buffer, length);

    /* If error, return invalid parameter */
    if (bytes_read < 0) {
        output_stream = guac_rdpdr_new_io_completion(device,
                iorequest->completion_id, guac_rdp_fs_get_status(bytes_read), 4);
        Stream_Write_UINT32(output_stream, 0); /* Length */
    }

    /* Otherwise, send bytes read */
    else {
        output_stream = guac_rdpdr_new_io_completion(device,
                iorequest->completion_id, STATUS_SUCCESS, 4+bytes_read);
        Stream_Write_UINT32(output_stream, bytes_read);  /* Length */
        Stream_Write(output_stream, buffer, bytes_read); /* ReadData */
    }

    guac_rdp_common_svc_write(svc, output_stream);
    free(buffer);

}

void guac_rdpdr_fs_process_write(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    UINT32 length;
    UINT64 offset;
    int bytes_written;

    wStream* output_stream;

    /* Check remaining length. */
    if (Stream_GetRemainingLength(input_stream) < 32) {
        guac_client_log(svc->client, GUAC_LOG_WARNING, "File Stream does not "
                "contain the expected number of bytes. File sharing may not "
                "work as expected.");
        return;
    }
    
    /* Read packet */
    Stream_Read_UINT32(input_stream, length);
    Stream_Read_UINT64(input_stream, offset);
    Stream_Seek(input_stream, 20); /* Padding */

    guac_client_log(svc->client, GUAC_LOG_DEBUG,
            "%s: [file_id=%i] length=%i, offset=%" PRIu64,
             __func__, iorequest->file_id, length, (uint64_t) offset);

    /* Attempt write */
    bytes_written = guac_rdp_fs_write((guac_rdp_fs*) device->data,
            iorequest->file_id, offset, Stream_Pointer(input_stream), length);

    /* If error, return invalid parameter */
    if (bytes_written < 0) {
        output_stream = guac_rdpdr_new_io_completion(device,
                iorequest->completion_id, guac_rdp_fs_get_status(bytes_written), 5);
        Stream_Write_UINT32(output_stream, 0); /* Length */
        Stream_Write_UINT8(output_stream, 0);  /* Padding */
    }

    /* Otherwise, send success */
    else {
        output_stream = guac_rdpdr_new_io_completion(device,
                iorequest->completion_id, STATUS_SUCCESS, 5);
        Stream_Write_UINT32(output_stream, bytes_written); /* Length */
        Stream_Write_UINT8(output_stream, 0);              /* Padding */
    }

    guac_rdp_common_svc_write(svc, output_stream);

}

void guac_rdpdr_fs_process_close(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    wStream* output_stream;
    guac_rdp_fs_file* file;

    guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i]",
            __func__, iorequest->file_id);

    /* Get file */
    file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, iorequest->file_id);
    if (file == NULL)
        return;

    /* If file was written to, and it's in the \Download folder, start stream */
    if (file->bytes_written > 0 &&
            strncmp(file->absolute_path, "\\Download\\", 10) == 0) {
        guac_client_for_owner(svc->client, guac_rdp_download_to_user, file->absolute_path);
        guac_rdp_fs_delete((guac_rdp_fs*) device->data, iorequest->file_id);
    }

    /* Close file */
    guac_rdp_fs_close((guac_rdp_fs*) device->data, iorequest->file_id);

    output_stream = guac_rdpdr_new_io_completion(device,
            iorequest->completion_id, STATUS_SUCCESS, 4);
    Stream_Write(output_stream, "\0\0\0\0", 4); /* Padding */

    guac_rdp_common_svc_write(svc, output_stream);

}

void guac_rdpdr_fs_process_volume_info(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    int fs_information_class;

    /* Check remaining length */
    if (Stream_GetRemainingLength(input_stream) < 4) {
        guac_client_log(svc->client, GUAC_LOG_WARNING, "File Stream does not "
                "contain the expected number of bytes. File sharing may not "
                "work as expected.");
        return;
    }
    
    Stream_Read_UINT32(input_stream, fs_information_class);

    /* Dispatch to appropriate class-specific handler */
    switch (fs_information_class) {

        case FileFsVolumeInformation:
            guac_rdpdr_fs_process_query_volume_info(svc, device, iorequest, input_stream);
            break;

        case FileFsSizeInformation:
            guac_rdpdr_fs_process_query_size_info(svc, device, iorequest, input_stream);
            break;

        case FileFsDeviceInformation:
            guac_rdpdr_fs_process_query_device_info(svc, device, iorequest, input_stream);
            break;

        case FileFsAttributeInformation:
            guac_rdpdr_fs_process_query_attribute_info(svc, device, iorequest, input_stream);
            break;

        case FileFsFullSizeInformation:
            guac_rdpdr_fs_process_query_full_size_info(svc, device, iorequest, input_stream);
            break;

        default:
            guac_client_log(svc->client, GUAC_LOG_DEBUG,
                    "Unknown volume information class: 0x%x", fs_information_class);
    }

}

void guac_rdpdr_fs_process_file_info(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    int fs_information_class;

    /* Check remaining length */
    if (Stream_GetRemainingLength(input_stream) < 4) {
        guac_client_log(svc->client, GUAC_LOG_WARNING, "File Stream does not "
                "contain the expected number of bytes. File sharing may not "
                "work as expected.");
        return;
    }
    
    Stream_Read_UINT32(input_stream, fs_information_class);

    /* Dispatch to appropriate class-specific handler */
    switch (fs_information_class) {

        case FileBasicInformation:
            guac_rdpdr_fs_process_query_basic_info(svc, device, iorequest, input_stream);
            break;

        case FileStandardInformation:
            guac_rdpdr_fs_process_query_standard_info(svc, device, iorequest, input_stream);
            break;

        case FileAttributeTagInformation:
            guac_rdpdr_fs_process_query_attribute_tag_info(svc, device, iorequest, input_stream);
            break;

        default:
            guac_client_log(svc->client, GUAC_LOG_DEBUG,
                    "Unknown file information class: 0x%x", fs_information_class);
    }

}

void guac_rdpdr_fs_process_set_volume_info(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    wStream* output_stream = guac_rdpdr_new_io_completion(device,
            iorequest->completion_id, STATUS_NOT_SUPPORTED, 0);

    guac_client_log(svc->client, GUAC_LOG_DEBUG,
            "%s: [file_id=%i] Set volume info not supported",
            __func__, iorequest->file_id);

    guac_rdp_common_svc_write(svc, output_stream);

}

void guac_rdpdr_fs_process_set_file_info(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    int fs_information_class;
    int length;

    /* Check remaining length */
    if (Stream_GetRemainingLength(input_stream) < 32) {
        guac_client_log(svc->client, GUAC_LOG_WARNING, "File stream does not "
                "contain the expected number of bytes. File sharing may not "
                "work as expected.");
        return;
    }
    
    Stream_Read_UINT32(input_stream, fs_information_class);
    Stream_Read_UINT32(input_stream, length); /* Length */
    Stream_Seek(input_stream, 24);            /* Padding */

    /* Dispatch to appropriate class-specific handler */
    switch (fs_information_class) {

        case FileBasicInformation:
            guac_rdpdr_fs_process_set_basic_info(svc, device, iorequest, length, input_stream);
            break;

        case FileEndOfFileInformation:
            guac_rdpdr_fs_process_set_end_of_file_info(svc, device, iorequest, length, input_stream);
            break;

        case FileDispositionInformation:
            guac_rdpdr_fs_process_set_disposition_info(svc, device, iorequest, length, input_stream);
            break;

        case FileRenameInformation:
            guac_rdpdr_fs_process_set_rename_info(svc, device, iorequest, length, input_stream);
            break;

        case FileAllocationInformation:
            guac_rdpdr_fs_process_set_allocation_info(svc, device, iorequest, length, input_stream);
            break;

        default:
            guac_client_log(svc->client, GUAC_LOG_DEBUG,
                    "Unknown file information class: 0x%x",
                    fs_information_class);
    }

}

void guac_rdpdr_fs_process_device_control(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    wStream* output_stream = guac_rdpdr_new_io_completion(device,
            iorequest->completion_id, STATUS_INVALID_PARAMETER, 4);

    guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] IGNORED",
            __func__, iorequest->file_id);

    /* No content for now */
    Stream_Write_UINT32(output_stream, 0);

    guac_rdp_common_svc_write(svc, output_stream);

}

void guac_rdpdr_fs_process_notify_change_directory(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] Not "
            "implemented", __func__, iorequest->file_id);

}

void guac_rdpdr_fs_process_query_directory(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    wStream* output_stream;

    guac_rdp_fs_file* file;
    int fs_information_class, initial_query;
    int path_length;

    const char* entry_name;

    /* Get file */
    file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, iorequest->file_id);
    if (file == NULL)
        return;

    if (Stream_GetRemainingLength(input_stream) < 9) {
        guac_client_log(svc->client, GUAC_LOG_WARNING, "File stream does not "
                "contain the expected number of bytes. File sharing may not "
                "work as expected.");
        return;
    }
    
    /* Read main header */
    Stream_Read_UINT32(input_stream, fs_information_class);
    Stream_Read_UINT8(input_stream,  initial_query);
    Stream_Read_UINT32(input_stream, path_length);

    /* If this is the first query, the path is included after padding */
    if (initial_query) {

        /*
         * Check to make sure Stream has at least the 23 padding bytes in it
         * prior to seeking.
         */
        if (Stream_GetRemainingLength(input_stream) < 23) {
            guac_client_log(svc->client, GUAC_LOG_WARNING, "File stream does "
                    "not contain the expected number of bytes. File sharing "
                    "may not work as expected.");
            return;
        }
        
        Stream_Seek(input_stream, 23);       /* Padding */

        /* Convert path to UTF-8 */
        guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), path_length/2 - 1,
                file->dir_pattern, sizeof(file->dir_pattern));

    }

    guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] "
            "initial_query=%i, dir_pattern=\"%s\"", __func__,
            iorequest->file_id, initial_query, file->dir_pattern);

    /* Find first matching entry in directory */
    while ((entry_name = guac_rdp_fs_read_dir((guac_rdp_fs*) device->data,
                    iorequest->file_id)) != NULL) {

        /* Convert to absolute path */
        char entry_path[GUAC_RDP_FS_MAX_PATH];
        if (guac_rdp_fs_convert_path(file->absolute_path,
                    entry_name, entry_path) == 0) {

            int entry_file_id;

            /* Pattern defined and match fails, continue with next file */
            if (guac_rdp_fs_matches(entry_path, file->dir_pattern))
                continue;

            /* Open directory entry */
            entry_file_id = guac_rdp_fs_open((guac_rdp_fs*) device->data,
                    entry_path, FILE_READ_DATA, 0, FILE_OPEN, 0);

            if (entry_file_id >= 0) {

                /* Dispatch to appropriate class-specific handler */
                switch (fs_information_class) {

                    case FileDirectoryInformation:
                        guac_rdpdr_fs_process_query_directory_info(svc, device,
                                iorequest, entry_name, entry_file_id);
                        break;

                    case FileFullDirectoryInformation:
                        guac_rdpdr_fs_process_query_full_directory_info(svc,
                                device, iorequest, entry_name, entry_file_id);
                        break;

                    case FileBothDirectoryInformation:
                        guac_rdpdr_fs_process_query_both_directory_info(svc,
                                device, iorequest, entry_name, entry_file_id);
                        break;

                    case FileNamesInformation:
                        guac_rdpdr_fs_process_query_names_info(svc, device,
                                iorequest, entry_name, entry_file_id);
                        break;

                    default:
                        guac_client_log(svc->client, GUAC_LOG_DEBUG,
                                "Unknown dir information class: 0x%x",
                                fs_information_class);
                }

                guac_rdp_fs_close((guac_rdp_fs*) device->data, entry_file_id);
                return;

            } /* end if file exists */
        } /* end if path valid */
    } /* end if entry exists */

    /*
     * Handle errors as a lack of files.
     */

    output_stream = guac_rdpdr_new_io_completion(device,
            iorequest->completion_id, STATUS_NO_MORE_FILES, 5);

    Stream_Write_UINT32(output_stream, 0); /* Length */
    Stream_Write_UINT8(output_stream, 0);  /* Padding */

    guac_rdp_common_svc_write(svc, output_stream);

}

void guac_rdpdr_fs_process_lock_control(guac_rdp_common_svc* svc,
        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
        wStream* input_stream) {

    wStream* output_stream = guac_rdpdr_new_io_completion(device,
            iorequest->completion_id, STATUS_NOT_SUPPORTED, 5);

    guac_client_log(svc->client, GUAC_LOG_DEBUG,
            "%s: [file_id=%i] Lock not supported",
            __func__, iorequest->file_id);

    Stream_Zero(output_stream, 5); /* Padding */

    guac_rdp_common_svc_write(svc, output_stream);

}

