#ifndef ODIN_NODEJS_UTILITIES_H
#define ODIN_NODEJS_UTILITIES_H

#include <odin.h>
#include <napi.h>
#include <string>
#include <atomic>

namespace OdinUtilities
{
    void ThrowNapiException(Napi::Env env, OdinError error, const char* message);
}

inline bool odin_is_error(OdinError code)
{
    return code != ODIN_ERROR_SUCCESS && code != ODIN_ERROR_NO_DATA;
}

/**
 * Event data base structure used to copy OdinEvent data as a base for sending events to JS side
 */
struct EventData {
    std::string Event; 
    std::string Json;  
};

/**
 * Data structure to store audio samples used to copy The AudioDataReceived event data.
 * Also carries a pointer to the pending callback counter for ref-counting.
 */
struct AudioSamples {
    short Data[1920]; 
    float OriginalData[1920];
    size_t Len;
    uint64_t PeerId;
    uint16_t MediaId;
    
    // Pointer to atomic counter for tracking pending callbacks
    // Set before NonBlockingCall, decremented in callback after execution
    std::atomic<int>* PendingCounterPtr = nullptr;

    void ConvertFloat32ToFloat16(const float *in_buffer, size_t in_buffer_len, short *out_buffer) {
        for (size_t i = 0; i < in_buffer_len; i++) {
            float f = in_buffer[i];
            if (f > 1.0f) f = 1.0f;
            else if (f < -1.0f) f = -1.0f;
            out_buffer[i] = (int16_t) (f * 32767.0f);
        }
    }

    void SetSamples(const float *samples, size_t len)
    {
        if (len > 1920) len = 1920; 
        ConvertFloat32ToFloat16(samples, len, Data);
        memcpy(OriginalData, samples, len * sizeof(float));
        Len = len;
    }
};

#endif //ODIN_NODEJS_UTILITIES_H