#pragma once
#include <robotics/v2/nexus_net_client.hpp>

using namespace robotics;
/**
 * @brief nexus_net_network_v1 是一个实现单例模式的网络管理类，负责客户端的启动、停止、事件绑定和远程调用等功能，主要用于基于配置文件的分布式网络服务。
 */
class nexus_net_network_v1 {
public:
	/**
	 * @brief 返回一个指向静态 nexus_net_network_v1 实例的指针，实现单例模式。
	 * @return 指向静态 nexus_net_network_v1 实例的指针。
	 */
	static nexus_net_network_v1* instance() {
		static nexus_net_network_v1 g_network;
		return &g_network;
	}
	/**
	 * @brief 销毁 network 对象并释放其相关资源。
	 */
	~nexus_net_network_v1() {
		stop();
	}
	/**
	 * @brief 如果存在配置文件，则启动客户端。
	 */
	void start() {
		if (v2::nexus_net_xml_config::is_config_file()) {
			client_->start();
		}
	}
	/**
	 * @brief 如果存在配置文件，则停止客户端。
	 */
	void stop() {
		if (v2::nexus_net_xml_config::is_config_file()) {
			client_->stop();
		}
	}
	/**
	 * @brief 将指定的回调函数和对象绑定到给定的键，并在配置文件模式下进行订阅。
	 * @tparam _Fn 回调函数的类型。
	 * @tparam _This 对象实例的类型。
	 * @param key 要绑定的键名。
	 * @param fn 要绑定的回调函数。
	 * @param ths 与回调函数关联的对象实例。
	 */
	template<typename _Fn, typename _This>
	void bind(std::string const& key, _Fn&& fn, _This&& ths) {
		if (v2::nexus_net_xml_config::is_config_file()) {
			if (!client_->subscribe(key, std::forward<_Fn>(fn), std::forward<_This>(ths))) {
				throw std::runtime_error("key不存在.");
			}
		}
	}
	/**
	 * @brief
	 * @tparam _Ret
	 * @tparam ..._Args
	 * @param key
	 * @param ...args
	 * @return
	 */
	template<typename _Ret, typename ..._Args>
	_Ret invoke(std::string const& key, _Args&&...args) {
		if (v2::nexus_net_xml_config::is_config_file()) {
			return client_->publisher<_Ret>(key, std::forward<_Args>(args)...);
		}
		return _Ret{};
	}
	/**
	 * @brief 调用
	 * @tparam _Ret
	 * @tparam ..._Args
	 * @param timeout
	 * @param key
	 * @param ...args
	 * @return
	 */
	template<typename _Ret, typename ..._Args>
	_Ret invoke(int timeout, std::string const& key, _Args&&...args) {
		if (v2::nexus_net_xml_config::is_config_file()) {
			return client_->publisher<_Ret>(key, std::forward<_Args>(args)...);
		}
		return _Ret{};
	}
	/**
	 * @brief 一个事件委托对象，用于处理授权相关的回调。
	 */
	v3::delegates<bool>			authorized_event;
private:
	/**
	 * @brief 初始化网络客户端并绑定相关事件处理函数。
	 */
	nexus_net_network_v1() {
		if (v2::nexus_net_xml_config::is_config_file()) {
			client_ = v2::nexus_net_multiple_client::instance();
			client_->connect_event.bind(&nexus_net_network_v1::on_connect, this);
			client_->disconnect_event.bind(&nexus_net_network_v1::on_disconnect, this);
			client_->authorized_event.bind(&nexus_net_network_v1::on_authorized, this);
		}
	}
private:
	/**
	 * @brief 处理分布式连接的回调，根据连接状态记录日志。
	 * @param status 表示连接是否成功的布尔值。为 true 表示连接成功，为 false 表示连接失败。
	 */
	void on_connect(bool status) {
		if (status) {
			LOG_INFO << "分布式成功v1.";
		}
		else {
			LOG_ERROR << "分布式失败v1.";
		}
	}
	/**
	 * @brief 处理分布式连接断开的事件并记录警告日志。
	 */
	void on_disconnect() {
		LOG_INFO << "分布式连接断开v1.";
	}
	/**
	 * @brief 处理授权结果的回调函数，根据授权状态记录日志并在成功时触发事件。
	 * @param status 表示授权是否成功的布尔值。
	 * @param  未命名的 std::string 参数，未在函数体内使用。
	 * @param  未命名的 std::string 参数，未在函数体内使用。
	 */
	void on_authorized(bool status, std::string const&, std::string const&) {
		authorized_event(status);
	}
private:
	/**
	 * @brief 指向 v2::nexus_net_multiple_client 类型对象的指针，初始值为 nullptr。
	 */
	v2::nexus_net_multiple_client* client_ = nullptr;
};