#include <stddef.h>
#include <stdint.h>

int errno = 0;

// Basic memory stubs
extern void* malloc(size_t size);
extern void free(void* ptr);

// Forward declare memset (defined below)
void* memset(void* s, int c, size_t n);

// Memory stubs moved to stubs.zig

// LwIP Panic Handler (for Membrane stack)
extern void console_write(const void* p, size_t len);

void nexus_lwip_panic(const char* msg) {
    const char* prefix = "\n[LwIP/Membrane] ASSERT FAIL: ";
    console_write(prefix, 30);
    
    // Print the message (assuming null-terminated)
    const char* p = msg;
    size_t len = 0;
    while (p[len]) len++;
    console_write(msg, len);
    
    const char* suffix = "\n";
    console_write(suffix, 1);
    
    // Halt
    while(1) {}
}

// String stubs
size_t strlen(const char* s) {
    size_t i = 0;
    while(s[i]) i++;
    return i;
}

int strncmp(const char *s1, const char *s2, size_t n) {
    for (size_t i = 0; i < n; i++) {
        if (s1[i] != s2[i]) return (unsigned char)s1[i] - (unsigned char)s2[i];
        if (s1[i] == 0) return 0;
    }
    return 0;
}

int atoi(const char* nptr) { return 0; }

// IO stubs
extern int write(int fd, const void *buf, size_t count);

int printf(const char *format, ...) {
    write(1, format, strlen(format));
    return 0;
}

int fwrite(const void *ptr, size_t size, size_t nmemb, void *stream) {
    return write(1, ptr, size * nmemb);
}

int fflush(void *stream) { return 0; }

// System stubs
extern void nexus_yield(void);
// void exit(int status) { while(1) { nexus_yield(); } } // Moved to libc_shim.zig
void (*signal(int sig, void (*func)(int)))(int) { return NULL; }

// LwIP Time
uint32_t sys_now() { return 0; }

// Utils
uint16_t htons(uint16_t h) {
    return (h << 8) | (h >> 8);
}

void* memcpy(void* dest, const void* src, size_t n) {
    uint8_t* d = dest;
    const uint8_t* s = src;
    for (size_t i = 0; i < n; i++) d[i] = s[i];
    return dest;
}

void* memset(void* s, int c, size_t n) {
    uint8_t* p = s;
    for (size_t i = 0; i < n; i++) p[i] = (uint8_t)c;
    return s;
}

int memcmp(const void *s1, const void *s2, size_t n) {
    const unsigned char *p1 = (const unsigned char *)s1;
    const unsigned char *p2 = (const unsigned char *)s2;
    for (size_t i = 0; i < n; i++) {
        if (p1[i] != p2[i]) return p1[i] - p2[i];
    }
    return 0;
}

void *memmove(void *dest, const void *src, size_t n) {
    char *d = (char *)dest;
    const char *s = (const char *)src;
    if (d < s) {
        for (size_t i = 0; i < n; i++) d[i] = s[i];
    } else {
        for (size_t i = n; i > 0; i--) d[i - 1] = s[i - 1];
    }
    return dest;
}

void console_write(const void* p, size_t len) {
    // Phase 7: Direct UART access for Proof of Life
    volatile char *uart = (volatile char *)0x10000000;
    const char *buf = (const char *)p;
    for (size_t i = 0; i < len; i++) {
        if (buf[i] == '\n') *uart = '\r';
        *uart = buf[i];
    }
}

void ion_egress_to_port(uint16_t port, void* pkt);
