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

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

uint32_t app_lvgl_get_idle_percent(void)
{
#if (configGENERATE_RUN_TIME_STATS == 1) && (configUSE_TRACE_FACILITY == 1)
    static TaskStatus_t *task_status = NULL;
    static UBaseType_t task_status_count = 0;
    static uint64_t last_total = 0;
    static uint64_t last_idle = 0;

    UBaseType_t count = uxTaskGetNumberOfTasks();
    if (count == 0) {
        return 0;
    }

    if (count > task_status_count) {
        TaskStatus_t *new_buf = (TaskStatus_t *)realloc(task_status, count * sizeof(TaskStatus_t));
        if (!new_buf) {
            return 0;
        }
        task_status = new_buf;
        task_status_count = count;
    }

    configRUN_TIME_COUNTER_TYPE total_runtime = 0;
    UBaseType_t filled = uxTaskGetSystemState(task_status, task_status_count, &total_runtime);

    uint64_t idle_runtime = 0;
    for (UBaseType_t i = 0; i < filled; i++) {
        const char *name = task_status[i].pcTaskName;
        if (name && strncmp(name, "IDLE", 4) == 0) {
            idle_runtime += (uint64_t)task_status[i].ulRunTimeCounter;
        }
    }

    uint64_t total_runtime64 = (uint64_t)total_runtime;
    if (last_total == 0 || total_runtime64 < last_total || idle_runtime < last_idle) {
        last_total = total_runtime64;
        last_idle = idle_runtime;
        return 0;
    }

    uint64_t total_delta = total_runtime64 - last_total;
    uint64_t idle_delta = idle_runtime - last_idle;
    last_total = total_runtime64;
    last_idle = idle_runtime;

    if (total_delta == 0) {
        return 0;
    }

    uint64_t pct = (idle_delta * 100U) / total_delta;
    if (pct > 100U) {
        pct = 100U;
    }
    return (uint32_t)pct;
#else
    return 0;
#endif
}
