/*
 * 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.
 */

#ifndef GUAC_COMMON_RECORDING_H
#define GUAC_COMMON_RECORDING_H

#include <guacamole/client.h>

/**
 * The maximum numeric value allowed for the .1, .2, .3, etc. suffix appended
 * to the end of the session recording filename if a recording having the
 * requested name already exists.
 */
#define GUAC_COMMON_RECORDING_MAX_SUFFIX 255

/**
 * The maximum length of the string containing a sequential numeric suffix
 * between 1 and GUAC_COMMON_RECORDING_MAX_SUFFIX inclusive, in bytes,
 * including NULL terminator.
 */
#define GUAC_COMMON_RECORDING_MAX_SUFFIX_LENGTH 4

/**
 * The maximum overall length of the full path to the session recording file,
 * including any additional suffix and NULL terminator, in bytes.
 */
#define GUAC_COMMON_RECORDING_MAX_NAME_LENGTH 2048

/**
 * An in-progress session recording, attached to a guac_client instance such
 * that output Guacamole instructions may be dynamically intercepted and
 * written to a file.
 */
typedef struct guac_common_recording {

    /**
     * The guac_socket which writes directly to the recording file, rather than
     * to any particular user.
     */
    guac_socket* socket;

    /**
     * Non-zero if output which is broadcast to each connected client
     * (graphics, streams, etc.) should be included in the session recording,
     * zero otherwise. Including output is necessary for any recording which
     * must later be viewable as video.
     */
    int include_output;

    /**
     * Non-zero if changes to mouse state, such as position and buttons pressed
     * or released, should be included in the session recording, zero
     * otherwise. Including mouse state is necessary for the mouse cursor to be
     * rendered in any resulting video.
     */
    int include_mouse;

    /**
     * Non-zero if keys pressed and released should be included in the session
     * recording, zero otherwise. Including key events within the recording may
     * be necessary in certain auditing contexts, but should only be done with
     * caution. Key events can easily contain sensitive information, such as
     * passwords, credit card numbers, etc.
     */
    int include_keys;

} guac_common_recording;

/**
 * Replaces the socket of the given client such that all further Guacamole
 * protocol output will be copied into a file within the given path and having
 * the given name. If the create_path flag is non-zero, the given path will be
 * created if it does not yet exist. If creation of the recording file or path
 * fails, error messages will automatically be logged, and no recording will be
 * written. The recording will automatically be closed once the client is
 * freed.
 *
 * @param client
 *     The client whose output should be copied to a recording file.
 *
 * @param path
 *     The full absolute path to a directory in which the recording file should
 *     be created.
 *
 * @param name
 *     The base name to use for the recording file created within the specified
 *     path.
 *
 * @param create_path
 *     Zero if the specified path MUST exist for the recording file to be
 *     written, or non-zero if the path should be created if it does not yet
 *     exist.
 *
 * @param include_output
 *     Non-zero if output which is broadcast to each connected client
 *     (graphics, streams, etc.) should be included in the session recording,
 *     zero otherwise. Including output is necessary for any recording which
 *     must later be viewable as video.
 *
 * @param include_mouse
 *     Non-zero if changes to mouse state, such as position and buttons pressed
 *     or released, should be included in the session recording, zero
 *     otherwise. Including mouse state is necessary for the mouse cursor to be
 *     rendered in any resulting video.
 *
 * @param include_keys
 *     Non-zero if keys pressed and released should be included in the session
 *     recording, zero otherwise. Including key events within the recording may
 *     be necessary in certain auditing contexts, but should only be done with
 *     caution. Key events can easily contain sensitive information, such as
 *     passwords, credit card numbers, etc.
 *
 * @return
 *     A new guac_common_recording structure representing the in-progress
 *     recording if the recording file has been successfully created and a
 *     recording will be written, NULL otherwise.
 */
guac_common_recording* guac_common_recording_create(guac_client* client,
        const char* path, const char* name, int create_path,
        int include_output, int include_mouse, int include_keys);

/**
 * Frees the resources associated with the given in-progress recording. Note
 * that, due to the manner that recordings are attached to the guac_client, the
 * underlying guac_socket is not freed. The guac_socket will be automatically
 * freed when the guac_client is freed.
 *
 * @param recording
 *     The guac_common_recording to free.
 */
void guac_common_recording_free(guac_common_recording* recording);

/**
 * Reports the current mouse position and button state within the recording.
 *
 * @param recording
 *     The guac_common_recording associated with the mouse that has moved.
 *
 * @param x
 *     The new X coordinate of the mouse cursor, in pixels.
 *
 * @param y
 *     The new Y coordinate of the mouse cursor, in pixels.
 *
 * @param button_mask
 *     An integer value representing the current state of each button, where
 *     the Nth bit within the integer is set to 1 if and only if the Nth mouse
 *     button is currently pressed. The lowest-order bit is the left mouse
 *     button, followed by the middle button, right button, and finally the up
 *     and down buttons of the scroll wheel.
 *
 *     @see GUAC_CLIENT_MOUSE_LEFT
 *     @see GUAC_CLIENT_MOUSE_MIDDLE
 *     @see GUAC_CLIENT_MOUSE_RIGHT
 *     @see GUAC_CLIENT_MOUSE_SCROLL_UP
 *     @see GUAC_CLIENT_MOUSE_SCROLL_DOWN
 */
void guac_common_recording_report_mouse(guac_common_recording* recording,
        int x, int y, int button_mask);

/**
 * Reports a change in the state of an individual key within the recording.
 *
 * @param recording
 *     The guac_common_recording associated with the key that was pressed or
 *     released.
 *
 * @param keysym
 *     The X11 keysym of the key that was pressed or released.
 *
 * @param pressed
 *     Non-zero if the key represented by the given keysym is currently
 *     pressed, zero if it is released.
 */
void guac_common_recording_report_key(guac_common_recording* recording,
        int keysym, int pressed);

#endif

