#include <stdint.h>
#include <stddef.h>
#include "netdev.h"
#include "spinlock/spinlock.h"
#include "kprintf.h"
#include "dlmalloc/malloc.h"
#include "errors.h"
#include "util/util.h"
#include "hal/hal.h"
#include "pico_device.h"
#include "pico_dev_loop.h"
#include "pico_ipv4.h"

NetDevList NETDEV_LIST;

void netdev_init(void) {
  spinlock_init(&NETDEV_LIST.spinlock);
  NETDEV_LIST.head = NULL;

  LOG("netdev", "init\n");

  netdev_create(NETDEV_LOOPBACK, "127.0.0.1", "255.255.255.0");
}

NetDev *netdev_create(int32_t ndtype, const char *ipaddrstring, const char *netmaskstring) {
  NetDev *nd = dlmalloc(sizeof(*nd));
  if (nd == NULL) {
    return NULL;
  }

  spinlock_acquire(&NETDEV_LIST.spinlock);

  nd->_magic = NETDEV_MAGIC;
  spinlock_init(&nd->spinlock);

  switch (ndtype) {
    case NETDEV_LOOPBACK: {
      nd->picodev = pico_loop_create();
    } break;
    default:
      dlfree(nd);
      spinlock_release(&NETDEV_LIST.spinlock);
      return NULL;
  }

  pico_string_to_ipv4(ipaddrstring, &nd->ipaddr4.addr);
  pico_string_to_ipv4(netmaskstring, &nd->netmask4.addr);
  pico_ipv4_link_add(nd->picodev, nd->ipaddr4, nd->netmask4);

  LL_APPEND(NETDEV_LIST.head, nd);
  spinlock_release(&NETDEV_LIST.spinlock);

  return nd;
}

// TODO: delete
