/*
 * 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 <CUnit/CUnit.h>
#include <guacamole/protocol.h>
#include <guacamole/socket.h>

#include <stdlib.h>
#include <unistd.h>

/**
 * Test string which contains exactly four Unicode characters encoded in UTF-8.
 * This particular test string uses several characters which encode to multiple
 * bytes in UTF-8.
 */
#define UTF8_4 "\xe7\x8a\xac\xf0\x90\xac\x80z\xc3\xa1"

/**
 * Writes a series of Guacamole instructions using a normal guac_socket
 * wrapping the given file descriptor. The instructions written correspond to
 * the instructions verified by read_expected_instructions(). The given file
 * descriptor is automatically closed as a result of calling this function.
 *
 * @param fd
 *     The file descriptor to write instructions to.
 */
static void write_instructions(int fd) {

    /* Open guac socket */
    guac_socket* socket = guac_socket_open(fd);

    /* Write nothing if socket cannot be allocated (test will fail in parent
     * process due to failure to read) */
    if (socket == NULL) {
        close(fd);
        return;
    }

    /* Write instructions */
    guac_protocol_send_name(socket, "a" UTF8_4 "b" UTF8_4 "c");
    guac_protocol_send_sync(socket, 12345);
    guac_socket_flush(socket);

    /* Close and free socket */
    guac_socket_free(socket);

}

/**
 * Reads raw bytes from the given file descriptor until no further bytes
 * remain, verfying that those bytes represent the series of Guacamole
 * instructions expected to be written by write_instructions(). The given
 * file descriptor is automatically closed as a result of calling this
 * function.
 *
 * @param fd
 *     The file descriptor to read data from.
 */
static void read_expected_instructions(int fd) {

    char expected[] =
        "4.name,11.a" UTF8_4 "b" UTF8_4 "c;"
        "4.sync,5.12345;";

    int numread;
    char buffer[1024];
    int offset = 0;

    /* Read everything available into buffer */
    while ((numread = read(fd, &(buffer[offset]),
                    sizeof(buffer) - offset)) > 0) {
        offset += numread;
    }

    /* Verify length of read data */
    CU_ASSERT_EQUAL(offset, strlen(expected));

    /* Add NULL terminator */
    buffer[offset] = '\0';

    /* Read value should be equal to expected value */
    CU_ASSERT_STRING_EQUAL(buffer, expected);

    /* File descriptor is no longer needed */
    close(fd);

}

/**
 * Tests that the file descriptor implementation of guac_socket properly
 * implements writing of instructions. A child process is forked to write a
 * series of instructions which are read and verified by the parent process.
 */
void test_socket__fd_send_instruction() {

    int fd[2];

    /* Create pipe */
    CU_ASSERT_EQUAL_FATAL(pipe(fd), 0);

    int read_fd = fd[0];
    int write_fd = fd[1];

    /* Fork into writer process (child) and reader process (parent) */
    int childpid;
    CU_ASSERT_NOT_EQUAL_FATAL((childpid = fork()), -1);

    /* Attempt to write a series of instructions within the child process */
    if (childpid == 0) {
        close(read_fd);
        write_instructions(write_fd);
        exit(0);
    }

    /* Read and verify the expected instructions within the parent process */
    close(write_fd);
    read_expected_instructions(read_fd);
 
}

