#pragma once

#include <types.h>

// === Unified string types ===
// Use these throughout the kernel instead of raw char*/const char*.

typedef const char* String;       // 8-bit narrow string
typedef const uint16_t* WString;  // 16-bit wide string (CHAR16)

// === Narrow string utilities (String) ===

static inline SUINT32 str_len(String s) {
    SUINT32 i = 0;
    while (s[i]) i++;
    return i;
}

static inline SSINT32 str_cmp(String a, String b) {
    while (*a && *a == *b) { a++; b++; }
    return (SUINT8)*a - (SUINT8)*b;
}

static inline bool str_eq(String a, String b) {
    return str_cmp(a, b) == 0;
}

// Copy up to max-1 chars, always null-terminates.
static inline void str_copy(char* dst, String src, SUINT32 max) {
    if (max == 0) return;
    SUINT32 i = 0;
    while (src[i] && i < max - 1) {
        dst[i] = src[i];
        i++;
    }
    dst[i] = '\0';
}

// === Wide string utilities (WString) ===

static inline SUINT32 wstr_len(WString s) {
    SUINT32 i = 0;
    while (s[i]) i++;
    return i;
}

static inline SSINT32 wstr_cmp(WString a, WString b) {
    while (*a && *a == *b) { a++; b++; }
    return (SUINT16)*a - (SUINT16)*b;
}

static inline bool wstr_eq(WString a, WString b) {
    return wstr_cmp(a, b) == 0;
}

static inline void wstr_copy(uint16_t* dst, WString src, SUINT32 max) {
    if (max == 0) return;
    SUINT32 i = 0;
    while (src[i] && i < max - 1) {
        dst[i] = src[i];
        i++;
    }
    dst[i] = 0;
}

// Convert wide string to ASCII (non-printable -> '?')
static inline void wstr_to_ascii(char* dst, WString src, SUINT32 max) {
    if (max == 0) return;
    SUINT32 i = 0;
    while (src[i] && i < max - 1) {
        if (src[i] >= 0x20 && src[i] <= 0x7E)
            dst[i] = (char)src[i];
        else
            dst[i] = '?';
        i++;
    }
    dst[i] = '\0';
}

// === Memory utilities ===

static inline void mem_set(void* dst, SUINT8 val, SUINT32 size) {
    SUINT8* d = (SUINT8*)dst;
    for (SUINT32 i = 0; i < size; i++) d[i] = val;
}

static inline void mem_copy(void* dst, const void* src, SUINT32 size) {
    SUINT8* d = (SUINT8*)dst;
    const SUINT8* s = (const SUINT8*)src;
    for (SUINT32 i = 0; i < size; i++) d[i] = s[i];
}
