
#include "cpumonfetcher.h"

cCpuMonFetcher::cCpuMonFetcher(cParameters *pparms): cThread("CPU Monitor Values Fetcher")
{
  // reset the index
  m_index = 0;
  v_index = 0;
  parms = pparms;
  // reset all values
  for(unsigned int a = 0; a < VAL_COUNT; a++)
  {
    measurements[a].val[USER]   = 0;
    measurements[a].val[NICE]   = 0;
    measurements[a].val[SYSTEM] = 0;
    measurements[a].val[IDLE]   = 0;
    measurements[a].used        = false;    
    measurements[a].sum         = 0;
    
    values[a].val[USER]   = 0;
    values[a].val[NICE]   = 0;
    values[a].val[SYSTEM] = 0;
    values[a].val[IDLE]   = 0;
    values[a].used        = false;    
    values[a].sum         = 0;
  }
};

cCpuMonFetcher::~cCpuMonFetcher()
{
  if( Running() )
    Cancel(3);
    
  delete measurements;
  delete values;
};

unsigned int cCpuMonFetcher::get_index()
{
  if(v_index <= 1)
    return 0;
  else
    return v_index - 1;
};

unsigned int cCpuMonFetcher::round(float x)
{
  unsigned int ax = (unsigned int) x;
  if ((ax - x) < 0.5)
    return x;
  else
    return x + 1;
};

int cCpuMonFetcher::fetch_values()
{
  Datei = fopen(DName, "r");  
  
  if(Datei)
  {
    if (m_index > VAL_COUNT)
      m_index = 0;
      
    if(v_index > VAL_COUNT - 1)
      v_index = 0;
    
    fscanf(Datei,
           "%s %u %u %u %u",
	   name,
	   &(measurements[m_index].val[USER]),
	   &(measurements[m_index].val[NICE]),
	   &(measurements[m_index].val[SYSTEM]),
	   &(measurements[m_index].val[IDLE])
	  );
			      
    measurements[m_index].used = true;				  
    fclose(Datei);
    gettimeofday(&(measurements[m_index].t_val), &t_zone);
    
    if(m_index > 0)
    {    
      values[v_index].val[USER]   = measurements[m_index].val[USER]   - measurements[m_index - 1].val[USER];
      values[v_index].val[NICE]   = measurements[m_index].val[NICE]   - measurements[m_index - 1].val[NICE];
      values[v_index].val[SYSTEM] = measurements[m_index].val[SYSTEM] - measurements[m_index - 1].val[SYSTEM];
      values[v_index].val[IDLE]   = measurements[m_index].val[IDLE]   - measurements[m_index - 1].val[IDLE];
    
      values[v_index].sum    = values[v_index].val[USER]   + 
                               values[v_index].val[NICE]   +
  			       values[v_index].val[SYSTEM] +
			       values[v_index].val[IDLE];

      float helper = 0;

      helper = 100 * (float) (values[v_index].val[USER]);
      helper /= (float) (values[v_index].sum);
      values[v_index].val[USER] = round(helper);

      helper = 100 * (float) (values[v_index].val[NICE]);
      helper /= (float) (values[v_index].sum);
      values[v_index].val[NICE] = round(helper);

      helper = 100 * (float)(values[v_index].val[SYSTEM]);
      helper /= (float) (values[v_index].sum);
      values[v_index].val[SYSTEM] = round(helper);

      helper = 100 * (float)(values[v_index].val[IDLE]);
      helper /= (float) (values[v_index].sum);
      values[v_index].val[IDLE] = round(helper);
			       
      values[v_index].sum    = values[v_index].val[USER]   + 
                               values[v_index].val[NICE]   +
  			       values[v_index].val[SYSTEM] +
			       values[v_index].val[IDLE];
			     
      values[v_index].used   = true;
      v_index++;
    }
    m_index++;
    return 0;
  }
  else
  {
    esyslog("ERROR: cCpuMonFetcher::fetch_values(): Opening of %s FAILED!\n", DName);
    return -1;
  }    
};

void cCpuMonFetcher::Action(void)
{  
  while( Running() )
  {
    fetch_values();    

    switch(parms->pi_unit())
    {
      case 0: // millsecs
        timer.Wait(parms->polling());
        break;
      case 1: // secs
        timer.Wait(parms->polling() * 1000);
        break;
      case 2: // minutes
        timer.Wait(parms->polling() * 60000);
        break;
      default:
        break;
    };
  };
  dsyslog("cCpuMonFetcher()::Action(): check parms->pi_unit\n");
};

void cCpuMonFetcher::Stop(void)
{
  Cancel(3);
};
