/*
 * ==========================================================================
 *         _   _      _   ____            __ __  __      _
 *        | \ | | ___| |_|  _ \ ___ _ __ / _|  \/  | ___| |_ ___ _ __
 *        |  \| |/ _ \ __| |_) / _ \ '__| |_| |\/| |/ _ \ __/ _ \ '__|
 *        | |\  |  __/ |_|  __/  __/ |  |  _| |  | |  __/ ||  __/ |
 *        |_| \_|\___|\__|_|   \___|_|  |_| |_|  |_|\___|\__\___|_|
 *
 *                  NetPerfMeter -- Network Performance Meter
 *                 Copyright (C) 2009-2026 by Thomas Dreibholz
 * ==========================================================================
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contact:  dreibh@simula.no
 * Homepage: https://www.nntb.no/~dreibh/netperfmeter/
 */

#ifndef CPUSTATUS_H
#define CPUSTATUS_H

#include <cassert>
#include <cstdint>
#include <cstdio>

#if defined(__APPLE__)
#include <mach/mach.h>
#endif


class CPUStatus
{
   // ====== Public methods =================================================
   public:
   CPUStatus();
   ~CPUStatus();

   void update();

   inline unsigned int getNumberOfCPUs() const {
      return CPUs;
   }
   inline unsigned int getCpuStates() const {
      return CpuStates;
   }
   inline const char* getCpuStateName(const unsigned int index) const {
      assert(index < CpuStates);
      return CpuStateNames[index];
   }
   inline float getCpuStatePercentage(const unsigned int cpuIndex,
                                      const unsigned int stateIndex) const {
      assert(cpuIndex <= CPUs);
      assert(stateIndex < CpuStates);
      const unsigned int index = (cpuIndex * CpuStates) + stateIndex;
      return Percentages[index];
   }
   float getCpuUtilization(const unsigned int cpuIndex) const;

   // ====== Private data ===================================================
   private:
#if defined(__linux__)
   typedef unsigned long long tick_t;
#elif defined(__NetBSD__)
   typedef uint64_t           tick_t;
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__)
   typedef unsigned long      tick_t;
#elif defined(__APPLE__)
   typedef unsigned int       tick_t;
#endif

#if defined(__linux__)
   FILE*               ProcStatFD;
#elif defined(__APPLE__)
   host_name_port_t    host;
#endif
   unsigned int        CPUs;
   tick_t*             CpuTimes;
   tick_t*             OldCpuTimes;
   float*              Percentages;
   unsigned int        CpuStates;
   static const char*  CpuStateNames[];
};

#endif
