#include "es_info.h"


int8_t getTemperature(uint8_t *temp) {
    FILE *fp;
    char path[1035];
    float temperature;

    // Use the 'cat' command to read the temperature from the thermal zone file
    fp = popen("cat /sys/class/thermal/thermal_zone0/temp", "r");
    if (fp == NULL) {
        perror("Error opening temperature file");
        exit(EXIT_FAILURE);
    }

    // Read the temperature from the file
    fgets(path, sizeof(path) - 1, fp);
    sscanf(path, "%f", &temperature);

    // Close the file
    pclose(fp);

    // Convert the temperature to degrees Celsius
    temperature /= 1000.0;
    *temp = (uint8_t)temperature;
    printf("temperature:%f\n",temperature);
    return 0;
}
#if 0
void printCpuPowerInfo() {
    FILE *fp;
    char buffer[256];

    // Run the cpupower command to get CPU power information
    fp = popen("cpupower frequency-info -o power", "r");
    if (fp == NULL) {
        perror("Error opening pipe");
        exit(EXIT_FAILURE);
    }

    // Read and print the output of the command
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
        printf("%s", buffer);
    }

    // Close the pipe
    if (pclose(fp) == -1) {
        perror("Error closing pipe");
        exit(EXIT_FAILURE);
    }
}

#endif

void getProcessorInfo(ps_get_chip_info_s *ps_get_chip_info) {
    FILE *file;
    char line[256];
    char processorName[256] = "";
    //    char chipID[256] = "";
    uint8_t chipID;

    // Open the /proc/cpuinfo file for reading
    file = fopen("/proc/cpuinfo", "r");
    if (file == NULL) {
        perror("Error opening /proc/cpuinfo");
        return;
    }
    // Read and extract processor name and chip ID
    while (fgets(line, sizeof(line), file) != NULL) {
        // Look for the "model name" line
        if (strncmp(line, "model name", 10) == 0) {
            sscanf(line, "model name\t: %[^\n]", processorName);
        }

        // Look for the "cpu family" line (contains chip ID)
        if (strncmp(line, "cpu family", 10) == 0) {
            sscanf(line, "cpu family\t: %hhd", &chipID);
        }
    }

    // Close the file
    fclose(file);

    // Print the extracted information
    printf("Processor Name: %s\n", processorName);
    printf("Chip ID: %hhd\n", chipID);
    strncpy(ps_get_chip_info->processor_name,processorName,sizeof(processorName)-1);
    ps_get_chip_info->processor_name[sizeof(processorName)-1] = '\0';
    ps_get_chip_info->chip_id = chipID;
}
#if 0
void printCpuCoreInfo() {
    FILE *fp;
    char line[256];
    int coreCount = 0;

    // Open the /proc/cpuinfo file for reading
    fp = fopen("/proc/cpuinfo", "r");
    if (fp == NULL) {
        perror("Error opening /proc/cpuinfo");
        exit(EXIT_FAILURE);
    }

    // Read and print information about each CPU core
    while (fgets(line, sizeof(line), fp) != NULL) {
        if (strstr(line, "processor") != NULL) {
            // Increment core count for each processor entry
            coreCount++;
            printf("\nCore %d:\n", coreCount);
        } else if (strstr(line, "model name") != NULL) {
            char coreType[256];
            sscanf(line, "model name\t: %[^\n]", coreType);
            printf("Type: %s\n", coreType);
        } else if (strstr(line, "cpu MHz") != NULL) {
            double coreFrequency;
            sscanf(line, "cpu MHz\t\t: %lf", &coreFrequency);
            printf("Frequency: %.2f MHz\n", coreFrequency);
        } else if (strstr(line, "Cpu") != NULL) {
            int isActive;
            sscanf(line, "Cpu%d\t\t: %d", &coreCount, &isActive);
            printf("Active: %s\n", (isActive == 1) ? "Yes" : "No");
        }
    }

    // Close the /proc/cpuinfo file
    fclose(fp);
}
#endif

void parseCpuInfo(FILE *file, CpuInfo *cpuInfo) {
    char line[256];

    // Reset the error count
    cpuInfo->err_count = 0;

    // Read each line of the file
    while (fgets(line, sizeof(line) - 1, file) != NULL) {
        // Extract CPU model name
        if (strstr(line, "model name") != NULL) {
            sscanf(line, "model name : %[^\n]", cpuInfo->model);
        }
        // Extract CPU core count
        else if (strstr(line, "cpu cores") != NULL) {
            sscanf(line, "cpu cores : %d", &cpuInfo->cores);
        }
        // Extract CPU clock speed
        else if (strstr(line, "cpu MHz") != NULL) {
            sscanf(line, "cpu MHz : %lf", &cpuInfo->clockSpeed);
        }
        // Extract CPU cache size
        else if (strstr(line, "cache size") != NULL) {
            sscanf(line, "cache size : %d KB", &cpuInfo->cacheSizeKB);
        }
        // Extract CPU features
        else if (strstr(line, "flags") != NULL) {
            sscanf(line, "flags :%x %x %x %x %x %x %x %x",
                    &cpuInfo->features[0], &cpuInfo->features[1],
                    &cpuInfo->features[2], &cpuInfo->features[3],
                    &cpuInfo->features[4], &cpuInfo->features[5],
                    &cpuInfo->features[6], &cpuInfo->features[7]);
        }
        else if (strstr(line, "err_count") != NULL) {
            sscanf(line, "err_count : %u", &cpuInfo->err_count);
        }
    }
}


void getCPUFeatures(ps_get_feature_s *ps_get_features) {
    CpuInfo cpuInfo;

    // Open /proc/cpuinfo for reading
    FILE *file = fopen("/proc/cpuinfo", "r");
    if (file == NULL) {
        perror("Error opening /proc/cpuinfo");
        // return 1;
    }

    // Parse CPU information
    parseCpuInfo(file, &cpuInfo);

    // Close the file
    fclose(file);

    // Print the extracted information
    printf("CPU Model: %s\n", cpuInfo.model);
    printf("Number of Cores: %d\n", cpuInfo.cores);
    printf("Clock Speed: %.2f MHz\n", cpuInfo.clockSpeed);
    printf("Cache Size: %d KB\n", cpuInfo.cacheSizeKB);

    // Print each feature
    printf("CPU Features:\n");
    for (int i = 0; i < 8; ++i) {
        printf("    Feature %d: 0x%x\n", i, cpuInfo.features[i]);
    }
    int clock_speed;
    // Print error count
    printf("Error Count: %u\n", cpuInfo.err_count);
    
    clock_speed = (int)cpuInfo.clockSpeed;
    memcpy(&ps_get_features->clock_speed,&clock_speed,sizeof(ps_get_features->clock_speed));
    memcpy(&ps_get_features->cores,&cpuInfo.cores,sizeof(ps_get_features->cores));
    memcpy(&ps_get_features->cache_size,&cpuInfo.cacheSizeKB,sizeof(ps_get_features->cache_size));
}

void printCPUUptime(uint32_t *uptime) {
    struct sysinfo info;

    // Get system information, including uptime
    if (sysinfo(&info) != 0) {
        perror("Error getting system information");
        exit(EXIT_FAILURE);
    }

    // Print CPU uptime
    printf("CPU Uptime: %ld seconds\n", info.uptime);
    *uptime=(uint32_t)info.uptime;
}

void printEpochTime(uint32_t *epoch_tm) {
    time_t epoch_time;

    // Get the current time in seconds since the epoch
    time(&epoch_time);

    // Print epoch time
    printf("Epoch Time: %ld seconds since the epoch\n", epoch_time);
    *epoch_tm=(uint32_t)epoch_time;
}
#if 0
void extractCacheInfo(FILE *file, struct CacheInfo *cache) {
    char buffer[256];

    // Read each line of the output
    while (fgets(buffer, sizeof(buffer) - 1, file) != NULL) {
        // Check if the line contains cache information
        if (strstr(buffer, "cache") != NULL) {
            // Parse the line and store information in the structure
            if (sscanf(buffer, "%*s %s %dK %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %d", cache->type, &cache->size, &cache->level) == 3) {
                return;  // Assuming there is only one entry for each cache level
            }
        }
    }
}
#endif
void extractMemoryInfo(FILE *file, const char *target, long *value) {
    char line[256];

    // Seek to the beginning of the file
    fseek(file, 0, SEEK_SET);

    // Read each line of the file
    while (fgets(line, sizeof(line), file) != NULL) {
        // Check if the line starts with the target string
        if (strncmp(line, target, strlen(target)) == 0) {
            // Extract the numeric value
            sscanf(line + strlen(target), "%ld", value);
            return;
        }
    }

    // If the target string is not found, set value to -1
    *value = -1;
}

void  printMemoryInfo(ps_get_ext_mem_s *ps_get_ext_mem) {
    FILE *file = fopen("/proc/meminfo", "r");
    if (file == NULL) {
        perror("Error opening /proc/meminfo");
        //return EXIT_FAILURE;
    }

    long memTotal, memFree, memAvailable;

    // Extract MemTotal
    extractMemoryInfo(file, "MemTotal:", &memTotal);
    printf("MemTotal: %ld kB\n", memTotal);

    // Extract MemFree
    extractMemoryInfo(file, "MemFree:", &memFree);
    printf("MemFree: %ld kB\n", memFree);

    // Extract MemAvailable
    extractMemoryInfo(file, "MemAvailable:", &memAvailable);
    printf("MemAvailable: %ld kB\n", memAvailable);
    memcpy(&ps_get_ext_mem->total_mem,&memTotal,sizeof(ps_get_ext_mem->total_mem));
    memcpy(&ps_get_ext_mem->available_mem,&memAvailable,sizeof(ps_get_ext_mem->available_mem));
    memcpy(&ps_get_ext_mem->free_mem,&memFree,sizeof(ps_get_ext_mem->free_mem));

    fclose(file);

    //return 0;
}

