/*
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#if PLATFORM(MAC)

#include "Test.h"
#include <WebCore/CARingBuffer.h>
#include <wtf/MainThread.h>

using namespace WebCore;

namespace TestWebKitAPI {

class CARingBufferTest : public testing::Test {
public:

    virtual void SetUp()
    {
        WTF::initializeMainThread();
        m_ringBuffer = std::make_unique<CARingBuffer>();
    }

    // CAAudioStreamDescription(double sampleRate, UInt32 numChannels, PCMFormat format, bool isInterleaved, size_t capacity)
    void setup(double sampleRate, UInt32 numChannels, CAAudioStreamDescription::PCMFormat format, bool isInterleaved, size_t capacity)
    {
        m_description = CAAudioStreamDescription(sampleRate, numChannels, format, isInterleaved);
        m_capacity = capacity;
        size_t listSize = offsetof(AudioBufferList, mBuffers) + (sizeof(AudioBuffer) * std::max<uint32_t>(1, m_description.numberOfChannelStreams()));
        m_bufferList = std::unique_ptr<AudioBufferList>(static_cast<AudioBufferList*>(::operator new (listSize)));
        m_ringBuffer->allocate(m_description, capacity);
    }

    void setListDataBuffer(uint8_t* bufferData, size_t sampleCount)
    {
        size_t bufferCount = m_description.numberOfChannelStreams();
        size_t channelCount = m_description.numberOfInterleavedChannels();
        size_t bytesPerChannel = sampleCount * m_description.bytesPerFrame();

        m_bufferList->mNumberBuffers = bufferCount;
        for (unsigned i = 0; i < bufferCount; ++i) {
            m_bufferList->mBuffers[i].mNumberChannels = channelCount;
            m_bufferList->mBuffers[i].mDataByteSize = bytesPerChannel;
            m_bufferList->mBuffers[i].mData = bufferData;
            if (bufferData)
                bufferData = bufferData + bytesPerChannel;
        }
    }

    const CAAudioStreamDescription& description() const { return m_description; }
    AudioBufferList& bufferList() const { return *m_bufferList.get(); }
    CARingBuffer& ringBuffer() const { return *m_ringBuffer.get(); }
    size_t capacity() const { return m_capacity; }

private:
    size_t audioBufferListSizeForStream(const CAAudioStreamDescription& format)
    {
        return offsetof(AudioBufferList, mBuffers) + (sizeof(AudioBuffer) * std::max<uint32_t>(1, format.numberOfChannelStreams()));
    }

    void configureBufferListForStream(AudioBufferList& bufferList, const CAAudioStreamDescription& format, uint8_t* bufferData, size_t sampleCount)
    {
        size_t bufferCount = format.numberOfChannelStreams();
        size_t channelCount = format.numberOfInterleavedChannels();
        size_t bytesPerChannel = sampleCount * format.bytesPerFrame();

        bufferList.mNumberBuffers = bufferCount;
        for (unsigned i = 0; i < bufferCount; ++i) {
            bufferList.mBuffers[i].mNumberChannels = channelCount;
            bufferList.mBuffers[i].mDataByteSize = bytesPerChannel;
            bufferList.mBuffers[i].mData = bufferData;
            if (bufferData)
                bufferData = bufferData + bytesPerChannel;
        }
    }

    std::unique_ptr<AudioBufferList> m_bufferList;
    std::unique_ptr<CARingBuffer> m_ringBuffer;
    CAAudioStreamDescription m_description = { };
    size_t m_capacity = { 0 };
};

TEST_F(CARingBufferTest, Basics)
{
    const int capacity = 32;

    setup(44100, 1, CAAudioStreamDescription::PCMFormat::Float32, true, capacity);

    float sourceBuffer[capacity];
    for (int i = 0; i < capacity; i++)
        sourceBuffer[i] = i + 0.5;

    setListDataBuffer(reinterpret_cast<uint8_t*>(sourceBuffer), capacity);

    // Fill the first half of the buffer ...
    int sampleCount = capacity / 2;
    CARingBuffer::Error err = ringBuffer().store(&bufferList(), sampleCount, 0);
    EXPECT_EQ(err, CARingBuffer::Error::Ok);

    uint64_t startTime;
    uint64_t endTime;
    ringBuffer().getCurrentFrameBounds(startTime, endTime);
    EXPECT_EQ(0, (int)startTime);
    EXPECT_EQ((int)sampleCount, (int)endTime);

    float scratchBuffer[capacity];
    setListDataBuffer(reinterpret_cast<uint8_t*>(scratchBuffer), capacity);

    err = ringBuffer().fetch(&bufferList(), sampleCount, 0);
    EXPECT_EQ(err, CARingBuffer::Error::Ok);
    EXPECT_TRUE(!memcmp(sourceBuffer, scratchBuffer, sampleCount * description().sampleWordSize()));

    // ... and the second half.
    err = ringBuffer().store(&bufferList(), capacity / 2, capacity / 2);
    EXPECT_EQ(err, CARingBuffer::Error::Ok);

    ringBuffer().getCurrentFrameBounds(startTime, endTime);
    EXPECT_EQ(0, (int)startTime);
    EXPECT_EQ(capacity, (int)endTime);

    memset(scratchBuffer, 0, sampleCount * description().sampleWordSize());
    err = ringBuffer().fetch(&bufferList(), sampleCount, 0);
    EXPECT_EQ(err, CARingBuffer::Error::Ok);
    EXPECT_TRUE(!memcmp(sourceBuffer, scratchBuffer, sampleCount * description().sampleWordSize()));

    // Force the buffer to wrap around
    err = ringBuffer().store(&bufferList(), capacity, capacity - 1);
    EXPECT_EQ(err, CARingBuffer::Error::Ok);

    ringBuffer().getCurrentFrameBounds(startTime, endTime);
    EXPECT_EQ((int)capacity - 1, (int)startTime);
    EXPECT_EQ(capacity - 1 + capacity, (int)endTime);

    // Make sure it returns an error when asked to store too much ...
    err = ringBuffer().store(&bufferList(), capacity * 3, capacity / 2);
    EXPECT_EQ(err, CARingBuffer::Error::TooMuch);

    // ... and doesn't modify the buffer
    ringBuffer().getCurrentFrameBounds(startTime, endTime);
    EXPECT_EQ((int)capacity - 1, (int)startTime);
    EXPECT_EQ(capacity - 1 + capacity, (int)endTime);

    ringBuffer().flush();
    ringBuffer().getCurrentFrameBounds(startTime, endTime);
    EXPECT_EQ(0, (int)startTime);
    EXPECT_EQ(0, (int)endTime);
}

template <typename type>
class MixingTest {
public:
    static void run(CARingBufferTest& test)
    {
        const int sampleCount = 64;

        CAAudioStreamDescription::PCMFormat format;
        if (std::is_same<type, float>::value)
            format = CAAudioStreamDescription::PCMFormat::Float32;
        else if (std::is_same<type, double>::value)
            format = CAAudioStreamDescription::PCMFormat::Float64;
        else if (std::is_same<type, int32_t>::value)
            format = CAAudioStreamDescription::PCMFormat::Int32;
        else if (std::is_same<type, int16_t>::value)
            format = CAAudioStreamDescription::PCMFormat::Int16;
        else
            ASSERT_NOT_REACHED();

        test.setup(44100, 1, format, true, sampleCount);

        type referenceBuffer[sampleCount];
        type sourceBuffer[sampleCount];
        type readBuffer[sampleCount];

        for (int i = 0; i < sampleCount; i++) {
            sourceBuffer[i] = i * 0.5;
            referenceBuffer[i] = sourceBuffer[i];
        }

        test.setListDataBuffer(reinterpret_cast<uint8_t*>(sourceBuffer), sampleCount);
        CARingBuffer::Error err = test.ringBuffer().store(&test.bufferList(), sampleCount, 0);
        EXPECT_EQ(err, CARingBuffer::Error::Ok);

        memset(readBuffer, 0, sampleCount * test.description().sampleWordSize());
        test.setListDataBuffer(reinterpret_cast<uint8_t*>(readBuffer), sampleCount);
        err = test.ringBuffer().fetch(&test.bufferList(), sampleCount, 0, CARingBuffer::FetchMode::Mix);
        EXPECT_EQ(err, CARingBuffer::Error::Ok);

        for (int i = 0; i < sampleCount; i++)
            EXPECT_EQ(readBuffer[i], referenceBuffer[i]) << "Ring buffer value differs at index " << i;

        err = test.ringBuffer().fetch(&test.bufferList(), sampleCount, 0, CARingBuffer::FetchMode::Mix);
        EXPECT_EQ(err, CARingBuffer::Error::Ok);
        err = test.ringBuffer().fetch(&test.bufferList(), sampleCount, 0, CARingBuffer::FetchMode::Mix);
        EXPECT_EQ(err, CARingBuffer::Error::Ok);
        err = test.ringBuffer().fetch(&test.bufferList(), sampleCount, 0, CARingBuffer::FetchMode::Mix);
        EXPECT_EQ(err, CARingBuffer::Error::Ok);

        for (int i = 0; i < sampleCount; i++)
            referenceBuffer[i] += sourceBuffer[i] * 3;
        
        for (int i = 0; i < sampleCount; i++)
            EXPECT_EQ(readBuffer[i], referenceBuffer[i]) << "Ring buffer value differs at index " << i;
    }
};

TEST_F(CARingBufferTest, FloatMixing)
{
    MixingTest<float>::run(*this);
}

TEST_F(CARingBufferTest, DoubleMixing)
{
    MixingTest<double>::run(*this);
}

TEST_F(CARingBufferTest, Int32Mixing)
{
    MixingTest<int32_t>::run(*this);
}

TEST_F(CARingBufferTest, Int16Mixing)
{
    MixingTest<int16_t>::run(*this);
}

}

#endif
