/*
 * Copyright 2010, Intel Corporation
 *
 * This file is part of PowerTOP
 *
 * This program file 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; version 2 of the License.
 *
 * 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 in a file named COPYING; if not, write to the
 * Free Software Foundation, Inc,
 * 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 * or just google for it.
 *
 * Authors:
 *	Arjan van de Ven <arjan@linux.intel.com>
 */
#pragma once

#include <cstdint>
#include <vector>
#include <algorithm>
#include <string>

#include "../lib.h"

extern double measurement_time;

class power_consumer;

/*
 * # subclasses of power_consumer
 *
 * | subclass        | filename                              |
 * | --------------- | ------------------------------------- |
 * | interrupt       | src/process/interrupt.h               |
 * | device_consumer | src/process/processdevice.h           |
 * | process         | src/process/process.h                 |
 * | timer           | src/process/timer.h                   |
 * | work            | src/process/work.h                    |
 */
class power_consumer {

public:
	uint64_t	accumulated_runtime = 0;
	uint64_t	child_runtime = 0;
	int		disk_hits = 0;
	int		wake_ups = 0;
	int		gpu_ops = 0;
	int		hard_disk_hits = 0;  /* those which are likely a wakeup of the disk */
	int		xwakes = 0;

	double		power_charge = 0.0;    /* power consumed by devices opened by this process */
	class power_consumer *waker = nullptr;
	class power_consumer *last_waker = nullptr;

	power_consumer(void);
	virtual ~power_consumer() {};

	virtual double Witts(void) const;
	virtual std::string description(void) { return ""; };

	virtual std::string name(void) const { return _("abstract"); };
	virtual std::string type(void) const { return _("abstract"); };

	virtual double usage(void) const;
	virtual std::string usage_units(void) const;

	virtual double usage_summary(void) const { return usage();};
	virtual std::string usage_units_summary(void) const { return usage_units(); };
	virtual double events(void) const { if (measurement_time < 0.00001) return 0.0; return  (wake_ups + gpu_ops + hard_disk_hits) / measurement_time;};
	virtual int show_events(void) const { return 1; };

	virtual void collect_json_fields(std::string &_js) const;
	std::string serialize() const { JSON_START(); collect_json_fields(_js); JSON_END(); }
};

extern std::vector <class power_consumer *> all_power;

extern double total_wakeups(void);
extern double total_cpu_time(void);
extern double total_gpu_ops(void);


