
#ifndef ETHERCAT_UTILS_HELP_H
#define ETHERCAT_UTILS_HELP_H

#pragma once

#include <stdint.h>
#include <string.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

static inline int bytes_to_string(const uint8_t* data, size_t maxLen,
                                         char* outBuf, size_t outBufSize)
{
    if (!data || !outBuf || outBufSize == 0) {
        if (outBuf && outBufSize > 0) outBuf[0] = 0;
        return 0;
    }

    size_t len = 0;
    while (len < maxLen && data[len] != 0) len++;
    if (len == 0) { outBuf[0] = 0; return 0; }

    bool validUtf8 = true;
    bool hasHighByte = false;
    for (size_t i = 0; i < len; ) {
        uint8_t b = data[i];
        if (b < 0x80) { i++; continue; }
        hasHighByte = true;
        int seqLen = 0;
        if ((b & 0xE0) == 0xC0) seqLen = 2;
        else if ((b & 0xF0) == 0xE0) seqLen = 3;
        else if ((b & 0xF8) == 0xF0) seqLen = 4;
        else { validUtf8 = false; break; }
        if (i + (size_t)seqLen > len) { validUtf8 = false; break; }
        for (int j = 1; j < seqLen; j++) {
            if ((data[i+j] & 0xC0) != 0x80) { validUtf8 = false; break; }
        }
        if (!validUtf8) break;
        i += (size_t)seqLen;
    }

    if (validUtf8) {
        size_t copyLen = (len < outBufSize - 1) ? len : outBufSize - 1;
        memcpy(outBuf, data, copyLen);
        outBuf[copyLen] = 0;
        return (int)copyLen;
    }

    size_t pos = 0;
    for (size_t i = 0; i < len && pos < outBufSize - 1; i++) {
        uint8_t b = data[i];
        if (b < 0x80) {
            outBuf[pos++] = (char)b;
        } else {

            if (pos + 2 > outBufSize - 1) break;
            outBuf[pos++] = (char)(0xC0 | (b >> 6));
            outBuf[pos++] = (char)(0x80 | (b & 0x3F));
        }
    }
    outBuf[pos] = 0;
    (void)hasHighByte;
    return (int)pos;
}

static inline void strncpy_safe(char* dst, const char* src, size_t dstSize)
{
    if (dstSize == 0) return;
    if (!dst) return;
    if (!src) { dst[0] = 0; return; }
    size_t len = strlen(src);
    if (len >= dstSize) len = dstSize - 1;
    memcpy(dst, src, len);
    dst[len] = 0;
}

#ifdef __cplusplus
}
#endif

#endif
