#pragma once

#include <string>
#include <vector>
#include <functional>
#include "MQTTAsync.h"
#include "common/JsonN.h"

class Station;
class Device;

struct TopicInfo
{
	std::string name;
	int deviceType {0};
	int polling {0}; // 召测
	int enabled {1};
	TopicInfo() {};
	TopicInfo(std::string name, int deviceType, int polling=0)
		:name(name), deviceType(deviceType), polling(polling)
	{};
};

using namespace std;

class MqttClient
{
public:
	static bool load(std::string filename);

	int init(string addr, string clientId, string username, string password);
	void destory();

	void subscribe();
	int publish(std::string topic, std::string text);
	int polling();

	void onConnectionLost(char* cause);
	void onDeliveryComplete(MQTTAsync_token token);

	void onConnectSuccess(MQTTAsync_successData* resp);
	void onConnectFaiure(MQTTAsync_failureData* resp);

	int onMessageArrived(char* topic, int len, MQTTAsync_message* msg);
	void ParseArrivedMessage(njson& json, string command, std::shared_ptr<Station> station);
	void ParseMessageCharge(njson& json, string command, std::shared_ptr<Station> station, std::shared_ptr<Device> device);

public:
	// MQTT clientId (使用station 的 code)
	std::string clientId;
	MQTTAsync client = nullptr;

	std::string addr;	// "tcp://localhost:1883"
	int qos {0};
	bool isConnected {false};
	bool isSubscribed {false};
	int64_t tsPolling {0};
	static std::map<std::string, TopicInfo> s_mapTopicInfo;
};


// <数据方向>/<数据格式>/<厂家ID>/<指令>/<设备标识，上行可选>
// Topic 字段说明
// 数据方向 :
//·down:下行，用于管理平台向厂家平台发送指令
// up :上行，用于厂家平台向管理平台推送设备应答或主报数据数据格式:基础格式为json，其他格式均为对json字符串进行二次编码
// json : body内的数据采用json编码
// base64 : body内数据先采用ison编码，然后再使用base64编码的字符串
// rsa : body内数据先采用json编码，然后采用 rsa 算法加密的base64字符串(rsa 密钥由管理平台提供)
// sm2 : body内数据先采用json编码，然后采用 sm2 算法加密的base64字符串(sm2 密钥由管理平台提供)
//·厂家ID : 由管理平台定义
//·命令ID : 用于指定读取/设置/控制的具体内容，如读取数据，读取时钟等等，具体参考 交互类指令协议设备标识 : 用于标识设备的唯一id，具体定义见3.2中的 context.dev_id 说明，上行时可不提供。

// <数据方向>/<数据格式>/<厂家ID>/<指令>/<设备标识，上行可选>
#define TOPIC_PCS_YC "up/json/预制舱01/PCS_YC"
#define TOPIC_PCS_YC "up/json/预制舱01/PCS_YC"

