/**
 * Wrapper file, which is used to test on PC hardware
 */
#ifndef ARDUINO_WRAP_H
#define ARDUINO_WRAP_H

#include <sys/time.h>
#include <unistd.h>

#define ARDUINO_ARCH_ESP8266
#define PAINLESSMESH_BOOST

#ifndef NULL
#define NULL 0
#endif

// Stub for non-AVR/ESP32 platforms (e.g., Linux, Windows, standard C++)
#ifndef __FlashStringHelper
#include <cstddef>  // for size_t
#include <cstring>  // for strcpy, strlen

class __FlashStringHelper {
 private:
  const char* str;

 public:
  // Constructor from a C string (for F("") macro simulation)
  __FlashStringHelper(const char* s) : str(s) {}

  // Allow implicit conversion to const char* for compatibility
  operator const char*() const { return str; }

  // Optional: Add methods to mimic Arduino's flash string behavior
  char charAt(size_t index) const { return str[index]; }
  size_t length() const { return strlen(str); }
};

// Define the F() macro to return a __FlashStringHelper
#define F(str) __FlashStringHelper(str)
#endif

inline unsigned long millis() {
  struct timeval te;
  gettimeofday(&te, NULL);  // get current time
  long long milliseconds =
      te.tv_sec * 1000LL + te.tv_usec / 1000;  // calculate milliseconds
  // printf("milliseconds: %lld\n", milliseconds);
  return milliseconds;
}

inline unsigned long micros() {
  struct timeval te;
  gettimeofday(&te, NULL);  // get current time
  long long milliseconds = te.tv_sec * 1000000LL + te.tv_usec;
  return milliseconds;
}

inline void delay(int i) { usleep(i); }

inline void yield() {}

/**
 * Override the configution file.
 **/

#ifndef _PAINLESS_MESH_CONFIGURATION_HPP_
#define _PAINLESS_MESH_CONFIGURATION_HPP_

#define _TASK_PRIORITY  // Support for layered scheduling priority
#define _TASK_STD_FUNCTION

#include <TaskSchedulerDeclarations.h>

#define ARDUINOJSON_USE_LONG_LONG 1
#include <ArduinoJson.h>
#undef ARDUINOJSON_ENABLE_ARDUINO_STRING

#define ICACHE_FLASH_ATTR

#define PAINLESSMESH_ENABLE_STD_STRING
#define PAINLESSMESH_ENABLE_OTA
#define NODE_TIMEOUT 10 * TASK_SECOND
// Minimum free memory, besides here all packets in queue are discarded.
#define MIN_FREE_MEMORY 4000
// MAX number of unsent messages in queue. Newer messages are discarded
#define MAX_MESSAGE_QUEUE 50

typedef std::string TSTRING;

#ifdef ESP32
#define MAX_CONN 10
#else
#define MAX_CONN 4
#endif  // DEBUG

#include "boost/asynctcp.hpp"
#include "fake_serial.hpp"

typedef enum {
  WL_NO_SHIELD = 255,  // for compatibility with WiFi Shield library
  WL_IDLE_STATUS = 0,
  WL_NO_SSID_AVAIL = 1,
  WL_SCAN_COMPLETED = 2,
  WL_CONNECTED = 3,
  WL_CONNECT_FAILED = 4,
  WL_CONNECTION_LOST = 5,
  WL_DISCONNECTED = 6
} wl_status_t;

class WiFiClass {
 public:
  void disconnect() {}
  auto status() { return WL_CONNECTED; }
};

class ESPClass {
 public:
  size_t getFreeHeap() { return 1e6; }
};

extern WiFiClass WiFi;
extern ESPClass ESP;

#endif
#endif
