// CPU負荷情報を取得.
//

#include "cpu.h"

typedef struct{
    long user;
    long nice;
    long system;
    long idel;
    long iowait;
    long irq;
    long softirq;
}cpu_t;

int get_cpu(cpu_t *cpu){
    char str[BUFSIZ];
    FILE *fp;

    fp = fopen("/proc/stat", "r");
    if(fp == NULL){
        return -1;
    }

    fgets(str, sizeof(str), fp);
    sscanf(str, "cpu %ld %ld %ld %ld %ld %ld %ld",
            &cpu->user, &cpu->nice, &cpu->system, &cpu->idel,
            &cpu->iowait, &cpu->irq, &cpu->softirq);

    fclose(fp);

    return 0;
}

long cpu_all_time(cpu_t *new_info, cpu_t *old_info){
    long ret;

    ret = (new_info->user - old_info->user) +
        (new_info->nice - old_info->nice) +
        (new_info->system - old_info->system) +
        (new_info->idel - old_info->idel) +
        (new_info->irq - old_info->irq) +
        (new_info->softirq - old_info->softirq);

    return ret;
}

long cpu_used_time(cpu_t *new_info, cpu_t *old_info){
    long ret;

    ret = (new_info->user - old_info->user) +
        (new_info->nice - old_info->nice) +
        (new_info->system - old_info->system) +
        (new_info->iowait - old_info->iowait) +
        (new_info->irq - old_info->irq) +
        (new_info->softirq - old_info->softirq);

    return ret;
}

double cpu_rate(cpu_t *new_info, cpu_t *old_info){
    long all, used;
    double rate;

    all = cpu_all_time(new_info, old_info);
    used = cpu_used_time(new_info, old_info);

    rate = (double)used/all*100;
    if(rate > 100){
        rate = 100;
    }

    return rate;
}

static cpu_t old_info ;
static cpu_t new_info ;
static int initFlag = 0 ;

int cpu_init() {
    int ret = get_cpu(&old_info);
    if(ret < 0){
        return -1;
    }
    initFlag = 1 ;
    return 0 ;
}

// CPU負荷率を取得.
double useCpu() {
    double ret = 0.0f ;
    if( initFlag == 0 ) {
        if( cpu_init() < 0 ) {
            return 0.0f ;
        }
        return 0.0f ;
    }
    if(get_cpu(&new_info) < 0){
        return 0.0f ;
    }
    ret = cpu_rate(&new_info, &old_info) ;
    old_info = new_info ;
    return ret ;
}

// プロセスIDを取得.
int getProcessId() {
    return (int)getpid() ;
}

