/*
 * 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 "beep.h"
#include "rdp.h"
#include "settings.h"

#include <freerdp/freerdp.h>
#include <guacamole/audio.h>
#include <guacamole/client.h>
#include <winpr/wtypes.h>

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

/**
 * Fills the given buffer with signed 8-bit, single-channel PCM at the given
 * sample rate which will produce a beep of the given frequency.
 *
 * @param buffer
 *     The buffer to fill with PCM data.
 *
 * @param frequency
 *     The frequency of the beep to generate, in hertz.
 *
 * @param rate
 *     The sample rate of the PCM to generate, in samples per second.
 *
 * @param buffer_size
 *     The number of bytes of PCM data to write to the given buffer.
 */
static void guac_rdp_beep_fill_square_wave(unsigned char* buffer,
        int frequency, int rate, int buffer_size) {

    int remaining = buffer_size;
    int current_value = GUAC_RDP_BEEP_AMPLITUDE;
    int pulse_width = rate / frequency / 2;

    /* Repeatedly write pulses (whose widths are determined by the desired
     * frequency) until buffer space is exhausted */
    while (remaining > 0) {

        /* Truncate pulse if insufficient space remains */
        int block_size = pulse_width;
        if (block_size > remaining)
            block_size = remaining;

        /* Write blocks, alternating the sign of the amplitude of each
         * successive block */
        memset(buffer, current_value, block_size);
        current_value = -current_value;

        buffer += block_size;
        remaining -= block_size;

    }

}

/**
 * Writes PCM data to the given guac_audio_stream which produces a beep of the
 * given frequency and duration. The provided guac_audio_stream may be
 * configured for any sample rate but MUST be configured for single-channel,
 * 8-bit PCM.
 *
 * @param audio
 *     The guac_audio_stream which should receive the PCM data.
 *
 * @param frequency
 *     The frequency of the beep, in hertz.
 *
 * @param duration
 *     The duration of the beep, in milliseconds.
 */
static void guac_rdp_beep_write_pcm(guac_audio_stream* audio,
        int frequency, int duration) {

    int buffer_size = audio->rate * duration / 1000;
    unsigned char* buffer = malloc(buffer_size);

    /* Beep for given frequency/duration using a simple square wave */
    guac_rdp_beep_fill_square_wave(buffer, frequency, audio->rate, buffer_size);
    guac_audio_stream_write_pcm(audio, buffer, buffer_size);

    free(buffer);

}

BOOL guac_rdp_beep_play_sound(rdpContext* context,
        const PLAY_SOUND_UPDATE* play_sound) {

    guac_client* client = ((rdp_freerdp_context*) context)->client;
    guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
    guac_rdp_settings* settings = rdp_client->settings;

    /* Ignore if audio is not enabled */
    if (!settings->audio_enabled) {
        guac_client_log(client, GUAC_LOG_DEBUG, "Ignoring request to beep "
                "for %" PRIu32 " millseconds at %" PRIu32 " Hz as audio is "
                "disabled.", play_sound->duration, play_sound->frequency);
        return TRUE;
    }

    /* Allocate audio stream which sends audio in a format supported by the
     * connected client(s) */
    guac_audio_stream* beep = guac_audio_stream_alloc(client, NULL,
            GUAC_RDP_BEEP_SAMPLE_RATE, 1, 8);

    /* Limit maximum duration of each beep */
    int duration = play_sound->duration;
    if (duration > GUAC_RDP_BEEP_MAX_DURATION)
        duration = GUAC_RDP_BEEP_MAX_DURATION;

    guac_rdp_beep_write_pcm(beep, play_sound->frequency, duration);
    guac_audio_stream_free(beep);

    return TRUE;

}

