#include "Enums.hpp"

#if defined(__linux__) || defined(__APPLE__)
#include <net/route.h>
#endif

namespace OverTheWire::Enums {

#define ENUM_VALUE(x) exports.Set(#x, Napi::Number::New(env, x))
#define ENUM_VALUE_MANUAL(x, y) exports.Set(#x, Napi::Number::New(env, y))

Napi::Object InitLinkLayerType(Napi::Env env, Napi::Object exports) {
  using namespace pcpp;
  ENUM_VALUE(LINKTYPE_NULL);
  ENUM_VALUE(LINKTYPE_ETHERNET);
  ENUM_VALUE(LINKTYPE_AX25);
  ENUM_VALUE(LINKTYPE_IEEE802_5);
  ENUM_VALUE(LINKTYPE_ARCNET_BSD);
  ENUM_VALUE(LINKTYPE_SLIP);
  ENUM_VALUE(LINKTYPE_PPP);
  ENUM_VALUE(LINKTYPE_FDDI);
  ENUM_VALUE(LINKTYPE_DLT_RAW1);
  ENUM_VALUE(LINKTYPE_DLT_RAW2);
  ENUM_VALUE(LINKTYPE_PPP_HDLC);
  ENUM_VALUE(LINKTYPE_PPP_ETHER);
  ENUM_VALUE(LINKTYPE_ATM_RFC1483);
  ENUM_VALUE(LINKTYPE_RAW);
  ENUM_VALUE(LINKTYPE_C_HDLC);
  ENUM_VALUE(LINKTYPE_IEEE802_11);
  ENUM_VALUE(LINKTYPE_FRELAY);
  ENUM_VALUE(LINKTYPE_LOOP);
  ENUM_VALUE(LINKTYPE_LINUX_SLL);
  ENUM_VALUE(LINKTYPE_LTALK);
  ENUM_VALUE(LINKTYPE_PFLOG);
  ENUM_VALUE(LINKTYPE_IEEE802_11_PRISM);
  ENUM_VALUE(LINKTYPE_IP_OVER_FC);
  ENUM_VALUE(LINKTYPE_SUNATM);
  ENUM_VALUE(LINKTYPE_IEEE802_11_RADIOTAP);
  ENUM_VALUE(LINKTYPE_ARCNET_LINUX);
  ENUM_VALUE(LINKTYPE_APPLE_IP_OVER_IEEE1394);
  ENUM_VALUE(LINKTYPE_MTP2_WITH_PHDR);
  ENUM_VALUE(LINKTYPE_MTP2);
  ENUM_VALUE(LINKTYPE_MTP3);
  ENUM_VALUE(LINKTYPE_SCCP);
  ENUM_VALUE(LINKTYPE_DOCSIS);
  ENUM_VALUE(LINKTYPE_LINUX_IRDA);
  ENUM_VALUE(LINKTYPE_USER0);
  ENUM_VALUE(LINKTYPE_USER1);
  ENUM_VALUE(LINKTYPE_USER2);
  ENUM_VALUE(LINKTYPE_USER3);
  ENUM_VALUE(LINKTYPE_USER4);
  ENUM_VALUE(LINKTYPE_USER5);
  ENUM_VALUE(LINKTYPE_USER6);
  ENUM_VALUE(LINKTYPE_USER7);
  ENUM_VALUE(LINKTYPE_USER8);
  ENUM_VALUE(LINKTYPE_USER9);
  ENUM_VALUE(LINKTYPE_USER10);
  ENUM_VALUE(LINKTYPE_USER11);
  ENUM_VALUE(LINKTYPE_USER12);
  ENUM_VALUE(LINKTYPE_USER13);
  ENUM_VALUE(LINKTYPE_USER14);
  ENUM_VALUE(LINKTYPE_USER15);
  ENUM_VALUE(LINKTYPE_IEEE802_11_AVS);
  ENUM_VALUE(LINKTYPE_BACNET_MS_TP);
  ENUM_VALUE(LINKTYPE_PPP_PPPD);
  ENUM_VALUE(LINKTYPE_GPRS_LLC);
  ENUM_VALUE(LINKTYPE_GPF_T);
  ENUM_VALUE(LINKTYPE_GPF_F);
  ENUM_VALUE(LINKTYPE_LINUX_LAPD);
  ENUM_VALUE(LINKTYPE_BLUETOOTH_HCI_H4);
  ENUM_VALUE(LINKTYPE_USB_LINUX);
  ENUM_VALUE(LINKTYPE_PPI);
  ENUM_VALUE(LINKTYPE_IEEE802_15_4);
  ENUM_VALUE(LINKTYPE_SITA);
  ENUM_VALUE(LINKTYPE_ERF);
  ENUM_VALUE(LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR);
  ENUM_VALUE(LINKTYPE_AX25_KISS);
  ENUM_VALUE(LINKTYPE_LAPD);
  ENUM_VALUE(LINKTYPE_PPP_WITH_DIR);
  ENUM_VALUE(LINKTYPE_C_HDLC_WITH_DIR);
  ENUM_VALUE(LINKTYPE_FRELAY_WITH_DIR);
  ENUM_VALUE(LINKTYPE_IPMB_LINUX);
  ENUM_VALUE(LINKTYPE_IEEE802_15_4_NONASK_PHY);
  ENUM_VALUE(LINKTYPE_USB_LINUX_MMAPPED);
  ENUM_VALUE(LINKTYPE_FC_2);
  ENUM_VALUE(LINKTYPE_FC_2_WITH_FRAME_DELIMS);
  ENUM_VALUE(LINKTYPE_IPNET);
  ENUM_VALUE(LINKTYPE_CAN_SOCKETCAN);
  ENUM_VALUE(LINKTYPE_IPV4);
  ENUM_VALUE(LINKTYPE_IPV6);
  ENUM_VALUE(LINKTYPE_IEEE802_15_4_NOFCS);
  ENUM_VALUE(LINKTYPE_DBUS);
  ENUM_VALUE(LINKTYPE_DVB_CI);
  ENUM_VALUE(LINKTYPE_MUX27010);
  ENUM_VALUE(LINKTYPE_STANAG_5066_D_PDU);
  ENUM_VALUE(LINKTYPE_NFLOG);
  ENUM_VALUE(LINKTYPE_NETANALYZER);
  ENUM_VALUE(LINKTYPE_NETANALYZER_TRANSPARENT);
  ENUM_VALUE(LINKTYPE_IPOIB);
  ENUM_VALUE(LINKTYPE_MPEG_2_TS);
  ENUM_VALUE(LINKTYPE_NG40);
  ENUM_VALUE(LINKTYPE_NFC_LLCP);
  ENUM_VALUE(LINKTYPE_INFINIBAND);
  ENUM_VALUE(LINKTYPE_SCTP);
  ENUM_VALUE(LINKTYPE_USBPCAP);
  ENUM_VALUE(LINKTYPE_RTAC_SERIAL);
  ENUM_VALUE(LINKTYPE_BLUETOOTH_LE_LL);
  ENUM_VALUE(LINKTYPE_NETLINK);
  ENUM_VALUE(LINKTYPE_BLUETOOTH_LINUX_MONITOR);
  ENUM_VALUE(LINKTYPE_BLUETOOTH_BREDR_BB);
  ENUM_VALUE(LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR);
  ENUM_VALUE(LINKTYPE_PROFIBUS_DL);
  ENUM_VALUE(LINKTYPE_PKTAP);
  ENUM_VALUE(LINKTYPE_EPON);
  ENUM_VALUE(LINKTYPE_IPMI_HPM_2);
  ENUM_VALUE(LINKTYPE_ZWAVE_R1_R2);
  ENUM_VALUE(LINKTYPE_ZWAVE_R3);
  ENUM_VALUE(LINKTYPE_WATTSTOPPER_DLM);
  ENUM_VALUE(LINKTYPE_ISO_14443);
  ENUM_VALUE(LINKTYPE_LINUX_SLL2);
  return exports;
}

#if defined(__linux__) || defined(__APPLE__)
Napi::Object InitRouteFlags(Napi::Env env, Napi::Object exports) {

#ifdef RTF_UP
  ENUM_VALUE(RTF_UP);
#endif
#ifdef RTF_GATEWAY
  ENUM_VALUE(RTF_GATEWAY);
#endif
#ifdef RTF_HOST
  ENUM_VALUE(RTF_HOST);
#endif
#ifdef RTF_REJECT
  ENUM_VALUE(RTF_REJECT);
#endif
#ifdef RTF_DYNAMIC
  ENUM_VALUE(RTF_DYNAMIC);
#endif
#ifdef RTF_MODIFIED
  ENUM_VALUE(RTF_MODIFIED);
#endif
#ifdef RTF_MULTICAST
  ENUM_VALUE(RTF_MULTICAST);
#endif

#ifdef RTF_DONE
  ENUM_VALUE(RTF_DONE);
#endif
#ifdef RTF_CLONING
  ENUM_VALUE(RTF_CLONING);
#endif
#ifdef RTF_XRESOLVE
  ENUM_VALUE(RTF_XRESOLVE);
#endif
#ifdef RTF_LLINFO
  ENUM_VALUE(RTF_LLINFO);
#endif
#ifdef RTF_STATIC
  ENUM_VALUE(RTF_STATIC);
#endif
#ifdef RTF_PROTO1
  ENUM_VALUE(RTF_PROTO1);
#endif
#ifdef RTF_PROTO2
  ENUM_VALUE(RTF_PROTO2);
#endif
#ifdef RTF_WASCLONED
  ENUM_VALUE(RTF_WASCLONED);
#endif
#ifdef RTF_PRCLONING
  ENUM_VALUE(RTF_PRCLONING);
#endif
#ifdef RTF_PROTO3
  ENUM_VALUE(RTF_PROTO3);
#endif
#ifdef RTF_BLACKHOLE
  ENUM_VALUE(RTF_BLACKHOLE);
#endif
#ifdef RTF_BROADCAST
  ENUM_VALUE(RTF_BROADCAST);
#endif
#ifdef RTF_IFSCOPE
  ENUM_VALUE(RTF_IFSCOPE);
#endif
#ifdef RTF_IFREF
  ENUM_VALUE(RTF_IFREF);
#endif
#ifdef RTF_PROXY
  ENUM_VALUE(RTF_PROXY);
#endif
#ifdef RTF_ROUTER
  ENUM_VALUE(RTF_ROUTER);
#endif
#ifdef RTF_GLOBAL
  ENUM_VALUE(RTF_GLOBAL);
#endif

  return exports;
}
#endif  // __linux__ || __APPLE__

Napi::Object Init(Napi::Env env, Napi::Object exports) {
  exports.Set("LinkLayerType", InitLinkLayerType(env, Napi::Object::New(env)));
#if defined(__linux__) || defined(__APPLE__)
  exports.Set("RouteFlags", InitRouteFlags(env, Napi::Object::New(env)));
#endif  // __linux__ || __APPLE__
  return exports;
}

#undef ENUM_VALUE
#undef ENUM_VALUE_MANUAL

} // namespace OverTheWire::Enums
