#ifndef MAINOBJECT_H
#define MAINOBJECT_H

#include <QObject>
#include <QDir>
#include <QDebug>
#include <QString>
#include <QTcpSocket>
#include <QFileInfo>
#include <QJsonDocument>
#include <QStandardPaths>
#include <memory>

#include "microcontroller.h"
#include "ui/mainwindow.h"
#include "sensors/sunsensor.h"
#include "sensors/mqttsensorsource.h"
#include "items/fixeditemsource.h"
#include "items/itemloadersource.h"
#include "service/tcpclient.h"
#include "service/tcpserver.h"
#include "service/websocketserver.h"

class MainObject : public QObject
{
	Q_OBJECT

public:
	explicit MainObject(QObject *parent = nullptr);
	~MainObject();
	static QJsonObject getJsonObjectFromDisk(const QString& filename, bool* error = nullptr);
	static bool storeJsonObjectToDisk(const QString& filename, const QJsonObject& json);

public slots:
	void refresh();
	virtual void addSensor(Sensor sensor, Sensor::sensor_backend_type_t backend, QJsonObject payload = {});
};

class PrimaryMainObject : public MainObject
{
	Q_OBJECT
public:

	QString settingsPath;
	QJsonObject settings;

	Microcontroller micro;
	TcpServer* tcpServer;
	WebSocketServer* webServer;
	std::shared_ptr<MqttClient> mqttClient;

	//sensors
	SunSensorSource sunSensorSource;
	MqttSensorSource mqttSensorSource;

	//item sources
	FixedItemSource fixedItems;
	ItemLoaderSource itemLoader;

public:
	explicit PrimaryMainObject(QIODevice* microDevice, const QString& settingsPath, const QString& host, int port, QObject *parent = nullptr);
	~PrimaryMainObject();
	void store(QJsonObject& json);
	void load(const QJsonObject& json);
	bool storeToDisk(const QString& filename);
	bool loadFromDisk(const QString& filename);
};

class SecondaryMainObject : public MainObject
{
	Q_OBJECT
public:
	TcpClient* tcpClient;

public:
	explicit SecondaryMainObject(QString host, int port, QObject *parent = nullptr);
	~SecondaryMainObject();
	void addSensor(Sensor sensor, Sensor::sensor_backend_type_t backend, QJsonObject payload = {}) override;

};

#endif // MAINOBJECT_H
