/**
 * @file string_utils.c
 * @brief 字符串工具函数实现
 */

#include "string_utils.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

char *str_utils_strdup(const char *src)
{
    if (!src) {
        return NULL;
    }
    size_t len = strlen(src);
    char *dst = (char *)malloc(len + 1);
    if (dst) {
        memcpy(dst, src, len + 1);
    }
    return dst;
}

bool str_utils_starts_with(const char *str, const char *prefix)
{
    if (!str || !prefix) {
        return false;
    }
    size_t str_len = strlen(str);
    size_t pre_len = strlen(prefix);
    if (pre_len > str_len) {
        return false;
    }
    return memcmp(str, prefix, pre_len) == 0;
}

bool str_utils_ends_with(const char *str, const char *suffix)
{
    if (!str || !suffix) {
        return false;
    }
    size_t str_len = strlen(str);
    size_t suf_len = strlen(suffix);
    if (suf_len > str_len) {
        return false;
    }
    return memcmp(str + str_len - suf_len, suffix, suf_len) == 0;
}

int str_utils_url_encode(const char *src, char *dst, size_t dst_size)
{
    if (!src || !dst || dst_size == 0) {
        return -1;
    }

    static const char hex[] = "0123456789ABCDEF";
    size_t si = 0, di = 0;

    while (src[si] && di < dst_size - 1) {
        char c = src[si++];
        if (isalnum((unsigned char)c) || c == '-' || c == '_' || c == '.' || c == '~') {
            dst[di++] = c;
        } else if (di + 3 < dst_size) {
            dst[di++] = '%';
            dst[di++] = hex[(unsigned char)c >> 4];
            dst[di++] = hex[(unsigned char)c & 0x0F];
        } else {
            break;
        }
    }
    dst[di] = '\0';
    return (int)di;
}

void str_utils_trim(char *str)
{
    if (!str || !str[0]) {
        return;
    }

    /* 去除头部空白 */
    char *start = str;
    while (*start && isspace((unsigned char)*start)) {
        start++;
    }

    /* 去除尾部空白 */
    char *end = start + strlen(start) - 1;
    while (end > start && isspace((unsigned char)*end)) {
        *end-- = '\0';
    }

    /* 如果头部有空白被跳过，移动数据 */
    if (start != str) {
        memmove(str, start, strlen(start) + 1);
    }
}
