/*
 * 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/audio-input/audio-buffer.h"
#include "plugins/guacai/guacai.h"
#include "plugins/guacai/guacai-messages.h"
#include "plugins/ptr-string.h"
#include "rdp.h"

#include <freerdp/dvc.h>
#include <freerdp/settings.h>
#include <guacamole/client.h>
#include <winpr/stream.h>
#include <winpr/wtsapi.h>
#include <winpr/wtypes.h>

#include <stdlib.h>

/**
 * Handles the given data received along the AUDIO_INPUT channel of the RDP
 * connection associated with the given guac_client. This handler is
 * API-independent and is invoked by API-dependent guac_rdp_ai_data callback
 * specific to the version of FreeRDP installed.
 *
 * @param client
 *     The guac_client associated with RDP connection having the AUDIO_INPUT
 *     connection along which the given data was received.
 *
 * @param channel
 *     A reference to the IWTSVirtualChannel instance along which responses
 *     should be sent.
 *
 * @param stream
 *     The data received along the AUDIO_INPUT channel.
 */
static void guac_rdp_ai_handle_data(guac_client* client,
        IWTSVirtualChannel* channel, wStream* stream) {

    /* Read message ID from received PDU */
    BYTE message_id;
    Stream_Read_UINT8(stream, message_id);

    /* Invoke appropriate message processor based on ID */
    switch (message_id) {

        /* Version PDU */
        case GUAC_RDP_MSG_SNDIN_VERSION:
            guac_rdp_ai_process_version(client, channel, stream);
            break;

        /* Sound Formats PDU */
        case GUAC_RDP_MSG_SNDIN_FORMATS:
            guac_rdp_ai_process_formats(client, channel, stream);
            break;

        /* Open PDU */
        case GUAC_RDP_MSG_SNDIN_OPEN:
            guac_rdp_ai_process_open(client, channel, stream);
            break;

        /* Format Change PDU */
        case GUAC_RDP_MSG_SNDIN_FORMATCHANGE:
            guac_rdp_ai_process_formatchange(client, channel, stream);
            break;

        /* Log unknown message IDs */
        default:
            guac_client_log(client, GUAC_LOG_DEBUG,
                    "Unknown AUDIO_INPUT message ID: 0x%x", message_id);

    }

}

/**
 * Callback which is invoked when data is received along a connection to the
 * AUDIO_INPUT plugin.
 *
 * @param channel_callback
 *     The IWTSVirtualChannelCallback structure to which this callback was
 *     originally assigned.
 *
 * @param stream
 *     The data received.
 *
 * @return
 *     Always zero.
 */
static UINT guac_rdp_ai_data(IWTSVirtualChannelCallback* channel_callback,
        wStream* stream) {

    guac_rdp_ai_channel_callback* ai_channel_callback =
        (guac_rdp_ai_channel_callback*) channel_callback;
    IWTSVirtualChannel* channel = ai_channel_callback->channel;

    /* Invoke generalized (API-independent) data handler */
    guac_rdp_ai_handle_data(ai_channel_callback->client, channel, stream);

    return CHANNEL_RC_OK;

}

/**
 * Callback which is invoked when a connection to the AUDIO_INPUT plugin is
 * closed.
 *
 * @param channel_callback
 *     The IWTSVirtualChannelCallback structure to which this callback was
 *     originally assigned.
 *
 * @return
 *     Always zero.
 */
static UINT guac_rdp_ai_close(IWTSVirtualChannelCallback* channel_callback) {

    guac_rdp_ai_channel_callback* ai_channel_callback =
        (guac_rdp_ai_channel_callback*) channel_callback;

    guac_client* client = ai_channel_callback->client;
    guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
    guac_rdp_audio_buffer* audio_buffer = rdp_client->audio_input;

    /* Log closure of AUDIO_INPUT channel */
    guac_client_log(client, GUAC_LOG_DEBUG,
            "AUDIO_INPUT channel connection closed");

    guac_rdp_audio_buffer_end(audio_buffer);
    free(ai_channel_callback);
    return CHANNEL_RC_OK;

}

/**
 * Callback which is invoked when a new connection is received by the
 * AUDIO_INPUT plugin. Additional callbacks required to handle received data
 * and closure of the connection must be installed at this point.
 *
 * @param listener_callback
 *     The IWTSListenerCallback structure associated with the AUDIO_INPUT
 *     plugin receiving the new connection.
 *
 * @param channel
 *     A reference to the IWTSVirtualChannel instance along which data related
 *     to the AUDIO_INPUT channel should be sent.
 *
 * @param data
 *     Absolutely no idea. According to Microsoft's documentation for the
 *     function prototype on which FreeRDP's API appears to be based: "This
 *     parameter is not implemented and is reserved for future use."
 *
 * @param accept
 *     Pointer to a flag which should be set to TRUE if the connection should
 *     be accepted or FALSE otherwise. In the case of FreeRDP, this value
 *     defaults to TRUE, and TRUE absolutely MUST be identically 1 or it will
 *     be interpreted as FALSE.
 *
 * @param channel_callback
 *     A pointer to the location that the new IWTSVirtualChannelCallback
 *     structure containing the required callbacks should be assigned.
 *
 * @return
 *     Always zero.
 */
static UINT guac_rdp_ai_new_connection(
        IWTSListenerCallback* listener_callback, IWTSVirtualChannel* channel,
        BYTE* data, int* accept,
        IWTSVirtualChannelCallback** channel_callback) {

    guac_rdp_ai_listener_callback* ai_listener_callback =
        (guac_rdp_ai_listener_callback*) listener_callback;

    /* Log new AUDIO_INPUT connection */
    guac_client_log(ai_listener_callback->client, GUAC_LOG_DEBUG,
            "New AUDIO_INPUT channel connection");

    /* Allocate new channel callback */
    guac_rdp_ai_channel_callback* ai_channel_callback =
        calloc(1, sizeof(guac_rdp_ai_channel_callback));

    /* Init listener callback with data from plugin */
    ai_channel_callback->client = ai_listener_callback->client;
    ai_channel_callback->channel = channel;
    ai_channel_callback->parent.OnDataReceived = guac_rdp_ai_data;
    ai_channel_callback->parent.OnClose = guac_rdp_ai_close;

    /* Return callback through pointer */
    *channel_callback = (IWTSVirtualChannelCallback*) ai_channel_callback;

    return CHANNEL_RC_OK;

}

/**
 * Callback which is invoked when the AUDIO_INPUT plugin has been loaded and
 * needs to be initialized with other callbacks and data.
 *
 * @param plugin
 *     The AUDIO_INPUT plugin that needs to be initialied.
 *
 * @param manager
 *     The IWTSVirtualChannelManager instance with which the AUDIO_INPUT plugin
 *     must be registered.
 *
 * @return
 *     Always zero.
 */
static UINT guac_rdp_ai_initialize(IWTSPlugin* plugin,
        IWTSVirtualChannelManager* manager) {

    /* Allocate new listener callback */
    guac_rdp_ai_listener_callback* ai_listener_callback =
        calloc(1, sizeof(guac_rdp_ai_listener_callback));

    /* Ensure listener callback is freed when plugin is terminated */
    guac_rdp_ai_plugin* ai_plugin = (guac_rdp_ai_plugin*) plugin;
    ai_plugin->listener_callback = ai_listener_callback;

    /* Init listener callback with data from plugin */
    ai_listener_callback->client = ai_plugin->client;
    ai_listener_callback->parent.OnNewChannelConnection =
        guac_rdp_ai_new_connection;

    /* Register listener for "AUDIO_INPUT" channel */
    manager->CreateListener(manager, "AUDIO_INPUT", 0,
            (IWTSListenerCallback*) ai_listener_callback, NULL);

    return CHANNEL_RC_OK;

}

/**
 * Callback which is invoked when all connections to the AUDIO_INPUT plugin
 * have closed and the plugin is being unloaded.
 *
 * @param plugin
 *     The AUDIO_INPUT plugin being unloaded.
 *
 * @return
 *     Always zero.
 */
static UINT guac_rdp_ai_terminated(IWTSPlugin* plugin) {

    guac_rdp_ai_plugin* ai_plugin = (guac_rdp_ai_plugin*) plugin;
    guac_client* client = ai_plugin->client;

    /* Free all non-FreeRDP data */
    free(ai_plugin->listener_callback);
    free(ai_plugin);

    guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT plugin unloaded.");
    return CHANNEL_RC_OK;

}

/**
 * Entry point for AUDIO_INPUT dynamic virtual channel.
 */
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) {

    /* Pull guac_client from arguments */
    ADDIN_ARGV* args = pEntryPoints->GetPluginData(pEntryPoints);
    guac_client* client = (guac_client*) guac_rdp_string_to_ptr(args->argv[1]);

    /* Pull previously-allocated plugin */
    guac_rdp_ai_plugin* ai_plugin = (guac_rdp_ai_plugin*)
        pEntryPoints->GetPlugin(pEntryPoints, "guacai");

    /* If no such plugin allocated, allocate and register it now */
    if (ai_plugin == NULL) {

        /* Init plugin callbacks and data */
        ai_plugin = calloc(1, sizeof(guac_rdp_ai_plugin));
        ai_plugin->parent.Initialize = guac_rdp_ai_initialize;
        ai_plugin->parent.Terminated = guac_rdp_ai_terminated;
        ai_plugin->client = client;

        /* Register plugin as "guacai" for later retrieval */
        pEntryPoints->RegisterPlugin(pEntryPoints, "guacai",
                (IWTSPlugin*) ai_plugin);

        guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT plugin loaded.");
    }

    return CHANNEL_RC_OK;

}

