#ifdef WITH_RIVE_AUDIO
#include "rive/math/simd.hpp"
#ifdef __APPLE__
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_MACCATALYST || TARGET_OS_IPHONE
// Don't define MINIAUDIO_IMPLEMENTATION ON iOS
#elif TARGET_OS_MAC
#define MINIAUDIO_IMPLEMENTATION
#else
#error "Unknown Apple platform"
#endif
#else
#define MINIAUDIO_IMPLEMENTATION
#endif
#include "miniaudio.h"

#include "rive/audio/audio_engine.hpp"
#include "rive/audio/audio_sound.hpp"
#include "rive/audio/audio_source.hpp"

#include <algorithm>

using namespace rive;

void AudioEngine::SoundCompleted(void* pUserData, ma_sound* pSound)
{
    AudioSound* audioSound = (AudioSound*)pUserData;
    auto engine = audioSound->m_engine;
    engine->soundCompleted(ref_rcp(audioSound));
}

void AudioEngine::soundCompleted(rcp<AudioSound> sound)
{
    std::unique_lock<std::mutex> lock(m_mutex);
    m_completedSounds.push_back(sound);

    auto next = sound->m_nextPlaying;
    auto prev = sound->m_prevPlaying;
    if (next != nullptr)
    {
        next->m_prevPlaying = prev;
    }
    if (prev != nullptr)
    {
        prev->m_nextPlaying = next;
    }

    if (m_playingSoundsHead == sound)
    {
        m_playingSoundsHead = next;
    }

    sound->m_nextPlaying = nullptr;
    sound->m_prevPlaying = nullptr;
}

#ifdef WITH_RIVE_AUDIO_TOOLS
namespace rive
{
class LevelsNode
{
public:
    ma_node_base base;
    AudioEngine* engine;
    static void measureLevels(ma_node* pNode,
                              const float** ppFramesIn,
                              ma_uint32* pFrameCountIn,
                              float** ppFramesOut,
                              ma_uint32* pFrameCountOut)
    {
        const float* frames = ppFramesIn[0];

        ma_uint32 frameCount = pFrameCountIn[0];

        static_cast<LevelsNode*>(pNode)->engine->measureLevels(frames, (uint32_t)frameCount);
    }
};
} // namespace rive

void AudioEngine::measureLevels(const float* frames, uint32_t frameCount)
{
    uint32_t channelCount = channels();

    for (uint32_t i = 0; i < frameCount; i++)
    {
        for (uint32_t c = 0; c < channelCount; c++)
        {
            float sample = *frames++;
            m_levels[c] = std::max(m_levels[c], sample);
        }
    }
}

static ma_node_vtable measure_levels_vtable = {LevelsNode::measureLevels,
                                               nullptr,
                                               1,
                                               1,
                                               MA_NODE_FLAG_PASSTHROUGH};

void AudioEngine::initLevelMonitor()
{
    if (m_levelMonitor == nullptr)
    {
        m_levelMonitor = new LevelsNode();
        m_levelMonitor->engine = this;

        ma_node_config nodeConfig = ma_node_config_init();
        nodeConfig.vtable = &measure_levels_vtable;
        uint32_t channelCount = channels();
        nodeConfig.pInputChannels = &channelCount;
        nodeConfig.pOutputChannels = &channelCount;
        m_levels.resize(channelCount);

        auto graph = ma_engine_get_node_graph(m_engine);
        if (ma_node_init(graph, &nodeConfig, nullptr, &m_levelMonitor->base) != MA_SUCCESS)
        {
            delete m_levelMonitor;
            m_levelMonitor = nullptr;
            return;
        }
        if (ma_node_attach_output_bus(&m_levelMonitor->base,
                                      0,
                                      ma_node_graph_get_endpoint(graph),
                                      0) != MA_SUCCESS)
        {
            ma_node_uninit(&m_levelMonitor->base, nullptr);
            delete m_levelMonitor;
            m_levelMonitor = nullptr;
            return;
        }
    }
}

void AudioEngine::levels(Span<float> levels)
{
    int size = std::min((int)m_levels.size(), (int)levels.size());
    for (int i = 0; i < size; i++)
    {
        levels[i] = m_levels[i];
        m_levels[i] = 0.0f;
    }
}

float AudioEngine::level(uint32_t channel)
{
    if (channel < m_levels.size())
    {
        float value = m_levels[channel];
        m_levels[channel] = 0.0f;
        return value;
    }
    return 0.0f;
}
#endif

rcp<AudioEngine> AudioEngine::Make(uint32_t numChannels, uint32_t sampleRate)
{
    ma_engine_config engineConfig = ma_engine_config_init();
    engineConfig.channels = numChannels;
    engineConfig.sampleRate = sampleRate;

#ifdef EXTERNAL_RIVE_AUDIO_ENGINE
    engineConfig.noDevice = MA_TRUE;
#endif

    ma_engine* engine = new ma_engine();

    if (ma_engine_init(&engineConfig, engine) != MA_SUCCESS)
    {
        fprintf(stderr, "AudioEngine::Make - failed to init engine\n");
        delete engine;
        return nullptr;
    }

    return rcp<AudioEngine>(new AudioEngine(engine));
}

uint32_t AudioEngine::channels() const { return ma_engine_get_channels(m_engine); }
uint32_t AudioEngine::sampleRate() const { return ma_engine_get_sample_rate(m_engine); }

AudioEngine::AudioEngine(ma_engine* engine) :
    m_device(ma_engine_get_device(engine)), m_engine(engine)
{}

rcp<AudioSound> AudioEngine::play(rcp<AudioSource> source,
                                  uint64_t startTime,
                                  uint64_t endTime,
                                  uint64_t soundStartTime)
{
    std::unique_lock<std::mutex> lock(m_mutex);
    // We have to dispose completed sounds out of the completed callback. So we
    // do it on next play or at destruct.
    for (auto sound : m_completedSounds)
    {
        sound->dispose();
    }
    m_completedSounds.clear();

    rcp<AudioSound> audioSound = rcp<AudioSound>(new AudioSound(this));
    if (source->isBuffered())
    {
        rive::Span<float> samples = source->bufferedSamples();
        ma_audio_buffer_config config =
            ma_audio_buffer_config_init(ma_format_f32,
                                        source->channels(),
                                        samples.size() / source->channels(),
                                        (const void*)samples.data(),
                                        nullptr);
        if (ma_audio_buffer_init(&config, audioSound->buffer()) != MA_SUCCESS)
        {
            fprintf(stderr, "AudioSource::play - Failed to initialize audio buffer.\n");
            return nullptr;
        }
        if (ma_sound_init_from_data_source(m_engine,
                                           audioSound->buffer(),
                                           MA_SOUND_FLAG_NO_PITCH | MA_SOUND_FLAG_NO_SPATIALIZATION,
                                           nullptr,
                                           audioSound->sound()) != MA_SUCCESS)
        {
            return nullptr;
        }
    }
    else
    {
        ma_decoder_config config = ma_decoder_config_init(ma_format_f32, channels(), sampleRate());
        auto sourceBytes = source->bytes();
        if (ma_decoder_init_memory(sourceBytes.data(),
                                   sourceBytes.size(),
                                   &config,
                                   audioSound->decoder()) != MA_SUCCESS)
        {
            fprintf(stderr, "AudioSource::play - Failed to initialize decoder.\n");
            return nullptr;
        }
        if (ma_sound_init_from_data_source(m_engine,
                                           &audioSound->m_decoder,
                                           MA_SOUND_FLAG_NO_PITCH | MA_SOUND_FLAG_NO_SPATIALIZATION,
                                           nullptr,
                                           audioSound->sound()) != MA_SUCCESS)
        {
            return nullptr;
        }
    }

    if (soundStartTime != 0)
    {
        audioSound->seek(soundStartTime);
    }

    ma_sound_set_end_callback(audioSound->sound(), SoundCompleted, audioSound.get());

    if (startTime != 0)
    {
        ma_sound_set_start_time_in_pcm_frames(audioSound->sound(), startTime);
    }
    if (endTime != 0)
    {
        ma_sound_set_stop_time_in_pcm_frames(audioSound->sound(), endTime);
    }
#ifdef WITH_RIVE_AUDIO_TOOLS
    if (m_levelMonitor != nullptr)
    {
        ma_node_attach_output_bus(audioSound->sound(), 0, m_levelMonitor, 0);
    }
#endif
    if (ma_sound_start(audioSound->sound()) != MA_SUCCESS)
    {
        fprintf(stderr, "AudioSource::play - failed to start sound\n");
        return nullptr;
    }

    if (m_playingSoundsHead != nullptr)
    {
        m_playingSoundsHead->m_prevPlaying = audioSound;
    }
    audioSound->m_nextPlaying = m_playingSoundsHead;
    m_playingSoundsHead = audioSound;

    return audioSound;
}

AudioEngine::~AudioEngine()
{
    auto sound = m_playingSoundsHead;
    while (sound != nullptr)
    {
        sound->dispose();

        auto next = sound->m_nextPlaying;
        sound->m_nextPlaying = nullptr;
        sound->m_prevPlaying = nullptr;
        sound = next;
    }

    for (auto sound : m_completedSounds)
    {
        sound->dispose();
    }
    m_completedSounds.clear();

    ma_engine_uninit(m_engine);
    delete m_engine;

#ifdef WITH_RIVE_AUDIO_TOOLS
    if (m_levelMonitor != nullptr)
    {
        ma_node_uninit(&m_levelMonitor->base, nullptr);
        delete m_levelMonitor;
    }

#endif
}

uint64_t AudioEngine::timeInFrames()
{
    return (uint64_t)ma_engine_get_time_in_pcm_frames(m_engine);
}

rcp<AudioEngine> AudioEngine::RuntimeEngine()
{
    static rcp<AudioEngine> engine = AudioEngine::Make(defaultNumChannels, defaultSampleRate);
    return engine;
}

#ifdef EXTERNAL_RIVE_AUDIO_ENGINE
bool AudioEngine::readAudioFrames(float* frames, uint64_t numFrames, uint64_t* framesRead)
{
    return ma_engine_read_pcm_frames(m_engine,
                                     (void*)frames,
                                     (ma_uint64)numFrames,
                                     (ma_uint64*)framesRead) == MA_SUCCESS;
}
bool AudioEngine::sumAudioFrames(float* frames, uint64_t numFrames)
{
    size_t numChannels = (size_t)channels();
    size_t count = (size_t)numFrames * numChannels;

    if (m_readFrames.size() < count)
    {
        m_readFrames.resize(count);
    }
    ma_uint64 framesRead = 0;
    if (ma_engine_read_pcm_frames(m_engine,
                                  (void*)m_readFrames.data(),
                                  (ma_uint64)numFrames,
                                  &framesRead) != MA_SUCCESS)
    {
        return false;
    }

    count = framesRead * numChannels;

    const size_t alignedCount = count - count % 4;
    float* src = m_readFrames.data();
    float* dst = frames;
    float* srcEnd = src + alignedCount;

    while (src != srcEnd)
    {
        float4 sum = simd::load4f(src) + simd::load4f(dst);
        simd::store(dst, sum);

        src += 4;
        dst += 4;
    }
    for (size_t i = alignedCount; i < count; i++)
    {
        frames[i] += m_readFrames[i];
    }
    return true;
}
#endif

#endif