/***************************************************************************
 * File Name: platform_linux.c
 * Description: Linux平台具体实现（基于POSIX接口）
 * Author: ZXY
 * Company: 芯祥联科技
 ***************************************************************************/
#ifdef LINUX
#include "type.h"
#include "platform.h"
#include "agent_log.h"

#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <stdio.h>
#include <sys/types.h>

// -------------------------- 线程实现 --------------------------
uint32_xxl platform_thread_id_linux(void) {
    return (uint32_xxl)pthread_self();
}

static void* thread_entry(void *arg) {
    PlatformThreadFunc func = (PlatformThreadFunc)arg;
    func(NULL);
    return NULL;
}

PlatformThread platform_thread_create_linux(PlatformThreadFunc func, void* arg) {
    pthread_t* tid = (pthread_t*)malloc(sizeof(pthread_t));
    if (tid == NULL) {
        agent_log_error("malloc pthread_t failed");
        return NULL;
    }

    int ret = pthread_create(tid, NULL, thread_entry, (void*)func);
    if (ret != 0) {
        agent_log_error("pthread_create failed");
        free(tid);
        return NULL;
    }
    return (PlatformThread)tid;
}

void platform_thread_join_linux(PlatformThread thread) {
    if (thread != NULL) {
        pthread_t* tid = (pthread_t*)thread;
        pthread_join(*tid, NULL);
        free(tid);
    }
}

void platform_thread_detach_linux(PlatformThread thread) {
    if (thread != NULL) {
        pthread_t* tid = (pthread_t*)thread;
        pthread_detach(*tid);
        free(tid);
    }
}

// -------------------------- 互斥锁实现 --------------------------
PlatformMutex platform_mutex_create_linux(void) {
    pthread_mutex_t* mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
    if (!mutex) {
        agent_log_error("malloc mutex failed");
        return NULL;
    }

    // 【修复】初始化失败必须free
    int ret = pthread_mutex_init(mutex, NULL);
    if (ret != 0) {
        agent_log_error("pthread_mutex_init failed");
        free(mutex);
        return NULL;
    }

    return (PlatformMutex)mutex;
}

void platform_mutex_lock_linux(PlatformMutex mutex) {
    if (mutex)
        pthread_mutex_lock((pthread_mutex_t*)mutex);
}

void platform_mutex_unlock_linux(PlatformMutex mutex) {
    if (mutex)
        pthread_mutex_unlock((pthread_mutex_t*)mutex);
}

void platform_mutex_destroy_linux(PlatformMutex mutex) {
    if (mutex == NULL) {
        return;
    }

    pthread_mutex_t* mutex_p = (pthread_mutex_t*)mutex;
    pthread_mutex_destroy(mutex_p);

    // 【修复】必须free！否则内存泄漏
    free(mutex);

}

// -------------------------- 信号量实现 --------------------------
PlatformSem platform_sem_create_linux(int initial_count, int max_count) {
    sem_t* sem = (sem_t*)malloc(sizeof(sem_t));
    if (!sem) {
        agent_log_error("malloc sem failed");
        return NULL;
    }

    int ret = sem_init(sem, 0, initial_count);
    if (ret != 0) {
        agent_log_error("sem_init failed");
        free(sem);
        return NULL;
    }

    return (PlatformSem)sem;
}

void platform_sem_destroy_linux(PlatformSem sem) {
    if (sem) {
        sem_destroy((sem_t*)sem);
        free(sem);
    }
}

int32_xxl platform_sem_post_linux(PlatformSem sem) {
    if (!sem) return -1;
    return (int32_xxl)sem_post((sem_t*)sem);
}

// 【修复】正确超时等待，不使用错误的 sem_trywait
int32_xxl platform_sem_timedwait_linux(PlatformSem sem, uint32_xxl timeout_ms) {
    if (!sem) return -1;

    struct timeval now;
    gettimeofday(&now, NULL);

    struct timespec ts;
    ts.tv_sec = now.tv_sec + timeout_ms / 1000;
    ts.tv_nsec = now.tv_usec * 1000 + (timeout_ms % 1000) * 1000000;

    if (ts.tv_nsec >= 1000000000) {
        ts.tv_sec++;
        ts.tv_nsec -= 1000000000;
    }

    // 【修复】使用正确的超时等待
    return sem_timedwait((sem_t*)sem, &ts);
}

// -------------------------- 平台初始化 --------------------------
bool_xxl platform_init_linux(void) {
    return true_xxl;
}

void platform_deinit_linux(void) {
}

// -------------------------- 时间 --------------------------
uint32_xxl platform_get_tick_ms_linux(void) {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (uint32_xxl)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
}

uint64_xxl platform_get_tick_us_linux(void) {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (uint64_xxl)tv.tv_sec * 1000000ULL + (uint64_xxl)tv.tv_usec;
}

PlatformTime platform_get_utc_seconds_linux(void) {
    return (PlatformTime)time(NULL);
}

PlatformTime platform_get_utc_ms_linux(void) {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (PlatformTime)((uint64_xxl)tv.tv_sec * 1000ULL + (uint64_xxl)tv.tv_usec / 1000ULL);
}

void platform_delay_ms_linux(uint32_xxl ms) {
    usleep(ms * 1000);
}

// -------------------------- 内存 --------------------------
void* platform_malloc_linux(uint32_xxl size) {
    return malloc((size_t)size);
}

void* platform_calloc_linux(uint32_xxl num, uint32_xxl size) {
    return calloc((size_t)num, (size_t)size);
}

void platform_free_linux(void* ptr) {
    free(ptr);
}

void* platform_malloc_aligned_linux(uint32_xxl size, uint32_xxl align) {
    return malloc(size);
}

void platform_free_aligned_linux(void* ptr) {
    free(ptr);
}

// -------------------------- 随机数 --------------------------
bool_xxl platform_rand_generate_linux(uint8_xxl* buf, uint32_xxl len) {
    uint32_xxl i;
    for (i = 0; i < len; i++) {
        buf[i] = (uint8_xxl)(rand() % 256);
    }
    return true_xxl;
}

bool_xxl platform_rand_generate_crypto_linux(uint8_xxl* buf, uint32_xxl len) {
    int fd = open("/dev/urandom", O_RDONLY);
    if (fd < 0) return false_xxl;

    ssize_t r = read(fd, buf, (size_t)len);
    close(fd);
    return (r > 0) ? true_xxl : false_xxl;
}

// -------------------------- 文件 --------------------------
bool_xxl platform_file_exists_linux(const char* path) {
    struct stat st;
    return (stat(path, &st) == 0) ? true_xxl : false_xxl;
}

uint32_xxl platform_get_file_size_linux(const char* path) {
    struct stat st;
    if (stat(path, &st) != 0) return 0;
    return (uint32_xxl)st.st_size;
}

// -------------------------- 内存/字符串 --------------------------
uint32_xxl platform_memset_s_linux(void* dest, uint32_xxl dest_max_len, uint8_xxl value, uint32_xxl set_len) {
    if (!dest || dest_max_len == 0) return 0;
    uint32_xxl actual = (set_len < dest_max_len) ? set_len : dest_max_len;
    memset(dest, (int)value, (size_t)actual);
    return actual;
}

int32_xxl platform_strcmp_linux(const char* a, const char* b) {
    return (int32_xxl)strcmp(a, b);
}

char* platform_strchr_linux(const char* s, int32_xxl c) {
    return strchr(s, (int)c);
}

// -------------------------- 运行时路径 --------------------------
uint32_xxl platform_get_runtime_filename_linux(char* buf, uint32_xxl buf_len) {
    if (!buf || buf_len == 0) return 0;

    char full_path[1024] = {0};
    readlink("/proc/self/exe", full_path, 1023);

    char *name = strrchr(full_path, '/');
    if (name) name++;
    else name = full_path;

    uint32_xxl l = (uint32_xxl)strlen(name);
    if (l >= buf_len) l = buf_len - 1;
    strncpy(buf, name, (size_t)l);
    buf[l] = 0;
    return l;
}

#endif
