/*
  *
  * This file is a part of Libcsys.
  * Library for getting system resource information in real time.
  * Copyright 2019 CuboCore Group
  *
  *
  *
  * 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, vsit http://www.gnu.org/licenses/.
  *
  */


#pragma once

#include <QFileInfoList>

#include "libcsys_global.h"

class Disk;
// class Process;
class CpuInfo;
class DiskInfo;
class MemoryInfo;
class NetworkInfo;
class SystemInfo;
// class ProcessInfo;

class LIBCSYSSHARED_EXPORT InfoManager {
public:
	InfoManager();
	InfoManager (const InfoManager&) = delete;
	InfoManager& operator= (const InfoManager&) = delete;
	~InfoManager();

	/** Maximum number of data points stored per resource */
	void setDataCount(int points);

	/** Update interval: DO NOT CHANGE THIS ONCE SET */
	void setUpdateInterval(int msecs);

	/**
	  * This is the heart of InfoManager.
	  * Call this function every @mInterval msecs.
	  * Each call to this function will add a data point.
	  */
	void update();

	/** DATA ACCESS FUNCTIONS */

	/**
	  *      CPU Related
	  */
	quint8 getCpuCoreCount() const;

	/** Get the latest @count number of data points.
	  * If @count = 0, return all the stored data points */
	QList<QList<double> > getCpuPercents(int count = 0) const;

	/** Get the latest @count number of data points.
	  * If @count = 0, return all the stored data points */
	QList<QList<double> > getCpuLoadAvgs(int count = 0) const;

	/** Get the latest @count number of data points.
	  * If @count = 0, return all the stored data points */
	QList<QList<double> > getCpuFrequencies(int count = 0) const;

	/** Current frequencies as a string */
	QStringList getCpuFrequenciesStr() const;

	/**
	  *      Memory Related
	  **/
	/** Get the latest @count number of data points.
	  * If @count = 0, return all the stored data points */
	QList<double> getMemUsed(int count = 0) const;

	/** Return the total available memory */
	quint64 getMemTotal() const;

	/** Get the latest @count number of data points.
	  * If @count = 0, return all the stored data points */
	QList<double> getSwapUsed(int count = 0) const;

	/** Return the total available swap area */
	quint64 getSwapTotal() const;

	/**
	  *      Network Related
	  **/

	/** Get the latest @count number of data points.
	  * If @count = 0, return all the stored data points
	  * This function returns a list of number of bytes of
	  *     (1) Recieved (Rx)
	  *     (2) Transmitted (Tx)
	  */
	QList<QList<double> > getNetworkUsage(int count = 0) const;

	/** Get the latest @count number of data points.
	  * If @count = 0, return all the stored data points
	  * This function returns the list of network speeds.
	  * These speeds are calculated as (current - previous) / interval.
	  */
	QList<QList<double> > getNetworkSpeed(int count = 0) const;          // Instantaneous network speed.

	/**
	  *      Disks Related
	  **/
	QList<Disk> getDisks() const;

	/** Get the latest @count number of data points.
	  * If @count = 0, return all the stored data points */
	QList<QList<double> > getDiskUsage(int count = 0) const;           // Disk usages - number of bytes used

	/** Get the latest @count number of data points.
	  * If @count = 0, return all the stored data points
	  * The speeds are calculated as (current - previous) / interval. */
	QList<QList<double> > getDiskSpeed(int count = 0) const;           // Read/write speed

	/**
	  *      Others Related
	  **/
	QFileInfoList getCrashReports() const;
	QFileInfoList getAppLogs() const;
	QFileInfoList getAppCaches() const;
	QString getUserName() const;

	void resetCPUUsages();
	void resetMemoryUsages();
	void resetNetworkUsages();
	void resetDiskUsages();

	void resetAllUsages();

private:
	CpuInfo *ci     = nullptr;
	DiskInfo *di    = nullptr;
	MemoryInfo *mi  = nullptr;
	NetworkInfo *ni = nullptr;
	SystemInfo *si  = nullptr;
	// ProcessInfo *pi = nullptr;

	int mDataPointsCount = 300;
	int mInterval        = 500;

	/**
	  * All the data will be stored as double.
	  * The data will be a list of lists: useful for grouping multiple resources
	  * Ex: For CPU Usages, we will have a list of <cpu-core-count> lists,
	  *     each list storing <mDataPointsCount> values.
	  */

	/** CPU related */
	QList<QList<double> > mCpuPercents;
	QList<QList<double> > mCpuLoadAverages;
	QList<QList<double> > mCpuFrequencies;

	/** Memory related */
	QList<double> mSwapUsage;
	QList<double> mRamUsage;

	/** Network related */
	QList<QList<double> > mNetworkUsage;
	QList<QList<double> > mNetworkSpeed;

	/** Disks related */
	QList<QList<double> > mDiskUsage;
	QList<QList<double> > mDiskSpeed;
};
