//
//  SwitchboardCore.hpp
//  SwitchboardSDK
//
//  Created by Balázs Kiss on 2022. 02. 22..
//  Copyright © 2022. Synervoz Inc. All rights reserved.
//

#pragma once

#include "SwitchboardVersion.hpp"
#include <switchboard_core/Platform.hpp>

#include <algorithm>
#include <atomic>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>

// MARK: - Types

// Check if data sizes are standard
static_assert(sizeof(char) == 1);
static_assert(sizeof(short) == 2);
static_assert(sizeof(int) == 4);
static_assert(sizeof(long long) == 8);

// Define fixed-size data types
using int8 = char;
using uint8 = unsigned char;
using int16 = int16_t;
using uint16 = uint16_t;
using int64 = int64_t;
using uint64 = uint64_t;
using uint = uint32_t;

// MARK: - Constants

namespace switchboard::constants {

static constexpr uint DEFAULT_SAMPLERATE = 44100;
static constexpr uint MAX_SAMPLERATE = 48000;
static constexpr uint MAX_BUFFER_DURATION_MS = 1000;
static constexpr uint MAX_NUMBER_OF_FRAMES = MAX_SAMPLERATE * MAX_BUFFER_DURATION_MS / 1000;
// ~85ms@48kHz or ~93ms@44.1kHz
static constexpr uint LEGACY_MAX_NUMBER_OF_FRAMES = 4096;

static constexpr uint NUM_CHANNELS_UNDEFINED = 0;
static constexpr uint MONO = 1;
static constexpr uint STEREO = 2;
static constexpr uint QUAD = 4;

static constexpr uint LEFT = 0;
static constexpr uint RIGHT = 1;

static constexpr uint SAMPLE_RATE_UNDEFINED = 0;
static constexpr uint SAMPLE_RATE_8KHz = 8000;
static constexpr uint SAMPLE_RATE_10KHz = 10000;
static constexpr uint SAMPLE_RATE_16KHz = 16000;
static constexpr uint SAMPLE_RATE_24KHz = 24000;
static constexpr uint SAMPLE_RATE_44_1KHz = 44100;
static constexpr uint SAMPLE_RATE_48KHz = 48000;

}

// MARK: - Preprocessor directives

// Web-specific defines
#if defined(SWITCHBOARD_WEB)
#include <emscripten.h>
#else
#endif

#if NETWORKING_ENABLED && SWITCHBOARD_LICENSE_VALIDATION_ENABLED
#define LICENSE_VALIDATION_ENABLED true
#else
#define LICENSE_VALIDATION_ENABLED false
#endif

#if !defined(M_PI)
#define M_PI 3.1415926535897932384626433832
#endif

#if !defined(M_PI_2)
#define M_PI_2 (M_PI / 2)
#endif

#if defined(__has_cpp_attribute) && __has_cpp_attribute(clang::nonblocking)
#define NONBLOCKING [[clang::nonblocking]]
#else
#define NONBLOCKING
#endif
