#include <stddef.h>
#include <stdint.h>
#include <stdarg.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);

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

void nexus_lwip_panic(const char* msg) {
    const char* prefix = "\n\x1b[1;31m[LwIP Fatal] ASSERTION FAILED: \x1b[0m";
    console_write(prefix, strlen(prefix));
    console_write(msg, strlen(msg));
    console_write("\n", 1);
    while(1) {}
}

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; }

double strtod(const char* nptr, char** endptr) {
    if (endptr) *endptr = (char*)nptr;
    return 0.0; 
}

double pow(double x, double y) { return 0.0; }
double log10(double x) { return 0.0; }

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

int printf(const char *format, ...) {
    va_list args;
    va_start(args, format);
    const char *p = format;
    while (*p) {
        if (*p == '%' && *(p+1)) {
            p++;
            if (*p == 's') {
                const char *s = va_arg(args, const char*);
                console_write(s, strlen(s));
            } else if (*p == 'd') {
                int i = va_arg(args, int);
                char buf[16];
                int len = 0;
                if (i == 0) { console_write("0", 1); }
                else {
                    if (i < 0) { console_write("-", 1); i = -i; }
                    while (i > 0) { buf[len++] = (i % 10) + '0'; i /= 10; }
                    for (int j = 0; j < len/2; j++) { char t = buf[j]; buf[j] = buf[len-1-j]; buf[len-1-j] = t; }
                    console_write(buf, len);
                }
            } else {
                console_write("%", 1);
                console_write(p, 1);
            }
        } else {
            console_write(p, 1);
        }
        p++;
    }
    va_end(args);
    return 0;
}

int sprintf(char *str, const char *format, ...) {
    if (str) str[0] = 0;
    return 0;
}

int snprintf(char *str, size_t size, const char *format, ...) {
    if (str && size > 0) str[0] = 0;
    return 0;
}

int vsnprintf(char *str, size_t size, const char *format, va_list ap) {
    if (str && size > 0) str[0] = 0;
    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 - moved to sys_arch.c
// uint32_t sys_now() { return 0; }

// RNG for LwIP (Project Prometheus)
int rand(void) {
    static unsigned long next = 1;
    next = next * 1103515245 + 12345;
    return (unsigned int)(next/65536) % 32768;
}

// 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);
