/* Sensor ringan C: membaca /proc (hanya-baca) lalu mencetak SATU baris JSON event "metrics" ke stdout.
 * Tidak membuka jaringan dan tidak menjalankan perintah shell; hak akses minimal.
 * Kompilasi: gcc -O2 -Wall -Wextra -o sensor_metrics sensor_metrics.c
 * Kirim ke mesin: ./run_c_sensor.sh (membungkus dengan curl) */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/statvfs.h>

static int read_cpu(unsigned long long *busy, unsigned long long *total) {
    FILE *f = fopen("/proc/stat", "r");
    if (!f) return -1;
    unsigned long long u, n, s, i, w, q, sq;
    int ok = fscanf(f, "cpu %llu %llu %llu %llu %llu %llu %llu", &u, &n, &s, &i, &w, &q, &sq);
    fclose(f);
    if (ok != 7) return -1;
    *total = u + n + s + i + w + q + sq;
    *busy = *total - i - w;
    return 0;
}

static int mem_percent(void) {
    FILE *f = fopen("/proc/meminfo", "r");
    if (!f) return -1;
    char key[64]; unsigned long long val, total = 0, avail = 0;
    char unit[16];
    while (fscanf(f, "%63s %llu %15s", key, &val, unit) >= 2) {
        if (strcmp(key, "MemTotal:") == 0) total = val;
        else if (strcmp(key, "MemAvailable:") == 0) avail = val;
    }
    fclose(f);
    return total ? (int)(100ULL * (total - avail) / total) : -1;
}

static int disk_percent(const char *path) {
    struct statvfs v;
    if (statvfs(path, &v) != 0 || v.f_blocks == 0) return -1;
    return (int)(100.0 * (double)(v.f_blocks - v.f_bavail) / (double)v.f_blocks);
}

int main(void) {
    unsigned long long b1, t1, b2, t2;
    if (read_cpu(&b1, &t1) != 0) return 1;
    sleep(1);
    if (read_cpu(&b2, &t2) != 0) return 1;
    int cpu = (t2 > t1) ? (int)(100ULL * (b2 - b1) / (t2 - t1)) : 0;
    printf("{\"type\":\"metrics\",\"metrics\":{\"cpu\":%d,\"mem\":%d,\"disk\":%d}}\n", cpu, mem_percent(), disk_percent("/"));
    return 0;
}
