//
// Copyright (c) 2023-2024 Ivica Siladic, Bruno Iljazovic, Korina Simicevic
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef ASYNC_MQTT5_LOGGER_TRAITS_HPP
#define ASYNC_MQTT5_LOGGER_TRAITS_HPP

#include <iostream>
#include <string_view>
#include <type_traits>

#include <boost/asio/ip/tcp.hpp>
#include <boost/system/error_code.hpp>
#include <boost/type_traits/is_detected.hpp>

#include <async_mqtt5/reason_codes.hpp>
#include <async_mqtt5/property_types.hpp>
#include <async_mqtt5/types.hpp>

namespace async_mqtt5 {

namespace asio = boost::asio;
using boost::system::error_code;

// NOOP Logger
class noop_logger {};

// at_resolve

template <typename T>
using at_resolve_sig = decltype(
	std::declval<T&>().at_resolve(
		std::declval<error_code>(),
		std::declval<std::string_view>(), std::declval<std::string_view>(),
		std::declval<const asio::ip::tcp::resolver::results_type&>()
	)
);
template <typename T>
constexpr bool has_at_resolve = boost::is_detected<at_resolve_sig, T>::value;

// at_tcp_connect

template <typename T>
using at_tcp_connect_sig = decltype(
	std::declval<T&>().at_tcp_connect(
		std::declval<error_code>(), std::declval<asio::ip::tcp::endpoint>()
	)
);
template <typename T>
constexpr bool has_at_tcp_connect = boost::is_detected<at_tcp_connect_sig, T>::value;

// at_tls_handshake

template <typename T>
using at_tls_handshake_sig = decltype(
	std::declval<T&>().at_tls_handshake(
		std::declval<error_code>(), std::declval<asio::ip::tcp::endpoint>()
	)
);
template <typename T>
constexpr bool has_at_tls_handshake = boost::is_detected<at_tls_handshake_sig, T>::value;

// at_ws_handshake

template <typename T>
using at_ws_handshake_sig = decltype(
	std::declval<T&>().at_ws_handshake(
		std::declval<error_code>(), std::declval<asio::ip::tcp::endpoint>()
	)
);
template <typename T>
constexpr bool has_at_ws_handshake = boost::is_detected<at_ws_handshake_sig, T>::value;

// at_connack

template <typename T>
using at_connack_sig = decltype(
	std::declval<T&>().at_connack(
		std::declval<reason_code>(),
		std::declval<bool>(), std::declval<const connack_props&>()
	)
);
template <typename T>
constexpr bool has_at_connack = boost::is_detected<at_connack_sig, T>::value;

// at_disconnect

template <typename T>
using at_disconnect_sig = decltype(
	std::declval<T&>().at_disconnect(
		std::declval<reason_code>(), std::declval<const disconnect_props&>()
	)
);
template <typename T>
constexpr bool has_at_disconnect = boost::is_detected<at_disconnect_sig, T>::value;

} // end namespace async_mqtt5


#endif // !ASYNC_MQTT5_LOGGER_TRAITS_HPP
