#pragma once

#ifndef PLATFORM_NATIVE

// ---------------------------------- Arduino -------------------------------------------------------------
#include "Logger.h"
#include <Arduino.h>

inline void _assert(const char *expression, const char *message, const char *file, int line)
{
    LOG_WARNING("Assert %s:%d '%s' failed.\n%s", file, line, expression, message);
}

template <typename T>
inline String toString(const T &t)
{
    return String(t);
}

#define assert_msg(EXPRESSION, MSG) ((EXPRESSION) ? (void)0 : _assert(#EXPRESSION, #MSG, __FILE__, __LINE__))

#else
// ---------------------------------- Native -----------------------------------------------------------------

#include <string>
#include <cstdint>
#include <cstring>
#include <arpa/inet.h>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>

typedef uint32_t uint_t;

typedef std::string String;
typedef uint8_t byte;
typedef const char *PGM_P;

using std::max;
using std::min;

inline uint32_t strlen_P(PGM_P str)
{
    return std::strlen(str);
}

inline const char *F(const char *in) { return in; }

inline void _assert(const char *expression, const char *message, const char *file, int line)
{
    std::cerr << "Assert " << file << ":" << line << "  '" << expression << "' failed." << std::endl;
    std::cerr << message << std::endl;

    abort();
}

template <typename T>
inline std::string toString(const T &t)
{
    std::stringstream stream;
    stream << t;
    return stream.str();
}

#define assert_msg(EXPRESSION, MSG) ((EXPRESSION) ? (void)0 : _assert(#EXPRESSION, #MSG, __FILE__, __LINE__))

#endif