#pragma once

#include "mqtt_basic.hpp"

#include <mosquitto.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <map>
#include <memory>
#include <functional>
#include <thread>
#include <mutex>

namespace mqtt_dataio
{
	class client
	{

	public:
		static client &ins()
		{
			static client ins;
			return ins;
		}

		void init(const std::string &ip, const uint16_t &port, const std::string &user, const std::string &pwd);

		void add_suber(const std::string &topic, mqtt_dataio::subscriber_basic *ptr);

		void rm_suber(const std::string &topic);

		void publish(const std::string &topic, const std::vector<uint8_t> &buff);

		~client();

	private:
		client() = default;

		static void on_connect(struct mosquitto *mosq, void *obj, int reason_code);

		static void on_subscribe(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos);

		static void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg);

	private:
		static bool __m_init;
		static struct mosquitto *__m_mosq;
		static std::shared_ptr<std::thread> __m_thread;
		static std::mutex __m_mtx;
		static std::map<std::string, mqtt_dataio::subscriber_basic *> __m_sub_list;
	};
}