/* Minimal C library for CubeCactusOS kernel
 * Provides basic functions without external dependencies
 */

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

/* VGA text mode buffer */
static uint16_t* const VGA_MEMORY = (uint16_t*)0xB8000;
static const int VGA_WIDTH = 80;
static const int VGA_HEIGHT = 25;
static int cursor_x = 0;
static int cursor_y = 0;

/* String functions */
size_t strlen(const char* str) {
    size_t len = 0;
    while (str[len])
        len++;
    return len;
}

void* memset(void* dest, int val, size_t count) {
    unsigned char* d = dest;
    while (count--)
        *d++ = (unsigned char)val;
    return dest;
}

void* memcpy(void* dest, const void* src, size_t count) {
    unsigned char* d = dest;
    const unsigned char* s = src;
    while (count--)
        *d++ = *s++;
    return dest;
}

/* Simple integer to string conversion */
static void itoa(int num, char* str, int base) {
    int i = 0;
    int isNegative = 0;
    
    if (num == 0) {
        str[i++] = '0';
        str[i] = '\0';
        return;
    }
    
    if (num < 0 && base == 10) {
        isNegative = 1;
        num = -num;
    }
    
    while (num != 0) {
        int rem = num % base;
        str[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
        num = num / base;
    }
    
    if (isNegative)
        str[i++] = '-';
    
    str[i] = '\0';
    
    /* Reverse string */
    int start = 0;
    int end = i - 1;
    while (start < end) {
        char temp = str[start];
        str[start] = str[end];
        str[end] = temp;
        start++;
        end--;
    }
}

/* Terminal output */
void putchar(char c) {
    if (c == '\n') {
        cursor_x = 0;
        cursor_y++;
    } else {
        const int index = cursor_y * VGA_WIDTH + cursor_x;
        VGA_MEMORY[index] = (uint16_t)c | 0x0F00;  /* White on black */
        cursor_x++;
        if (cursor_x >= VGA_WIDTH) {
            cursor_x = 0;
            cursor_y++;
        }
    }
    
    if (cursor_y >= VGA_HEIGHT) {
        cursor_y = 0;
        cursor_x = 0;
    }
}

void puts(const char* str) {
    while (*str) {
        putchar(*str++);
    }
}

/* Simple printf implementation */
int printf(const char* format, ...) {
    va_list args;
    va_start(args, format);
    
    char buffer[32];
    int written = 0;
    
    while (*format) {
        if (*format == '%') {
            format++;
            switch (*format) {
                case 's': {
                    const char* s = va_arg(args, const char*);
                    puts(s);
                    written += strlen(s);
                    break;
                }
                case 'd': {
                    int d = va_arg(args, int);
                    itoa(d, buffer, 10);
                    puts(buffer);
                    written += strlen(buffer);
                    break;
                }
                case 'x': {
                    int x = va_arg(args, int);
                    itoa(x, buffer, 16);
                    puts(buffer);
                    written += strlen(buffer);
                    break;
                }
                case '%':
                    putchar('%');
                    written++;
                    break;
                default:
                    putchar('%');
                    putchar(*format);
                    written += 2;
            }
        } else {
            putchar(*format);
            written++;
        }
        format++;
    }
    
    va_end(args);
    return written;
}

/* I/O port functions */
void outb(uint16_t port, uint8_t value) {
    __asm__ volatile ("outb %0, %1" : : "a"(value), "Nd"(port));
}

uint8_t inb(uint16_t port) {
    uint8_t ret;
    __asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
    return ret;
}

/* Stub IPC functions */
int send(int dest, void* msg) {
    (void)dest;
    (void)msg;
    return 0;
}

int receive(int source, void* msg) {
    (void)source;
    (void)msg;
    return 0;
}

int sendrec(int dest, void* msg) {
    (void)dest;
    (void)msg;
    return 0;
}
