//! \~\file pimqtttypes.h
//! \~\ingroup MQTT
//! \~\brief
//! \~english
//! \~russian
/*
	PIP - Platform Independent Primitives
	MQTT common types
	Ivan Pelipenko peri4ko@yandex.ru

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef pimqtttypes_h
#define pimqtttypes_h

#include "pip_export.h"
#include "pistringlist.h"


//! \~english Namespace with shared MQTT data types.
//! \~russian Пространство имен с общими MQTT-типами данных.
namespace PIMQTT {


//! \~english MQTT QoS type.
//! \~russian MQTT тип QoS.
enum class QoS {
	Level0 = 0 /** \~english Fire and forget - the message may not be delivered.  */,
	Level1 = 1 /** \~english At least once - the message will be delivered, but may be delivered more than once in some circumstances.  */,
	Level2 = 2 /** \~english Once and one only - the message will be delivered exactly once.  */,
};

enum class Error {
	Unknown                     = 0 /** */,
	UnacceptableProtocolVersion = 1 /** */,
	IdentifierRejected          = 2 /** */,
	ServerUnavailable           = 3 /** */,
	BadUsernameOrPassword       = 4 /** */,
	NotAuthorized               = 5 /** */,
};


//! \~\ingroup MQTT
//! \~\brief
//! \~english Immutable MQTT message.
//! \~russian Неизменяемое MQTT-сообщение.
class PIP_EXPORT MessageConst {
public:
	//! \~english Returns if the topic is not empty.
	//! \~russian Возвращает не пустой ли топик.
	bool isValid() const { return m_topic.isNotEmpty(); }

	//! \~english Returns the topic.
	//! \~russian Возвращает топик.
	const PIString & topic() const { return m_topic; }

	//! \~english Returns the topic split into non-empty components.
	//! \~russian Возвращает топик, разбитый на непустые компоненты.
	PIStringList topicList() const { return m_topic.split('/').removeAll({}); }

	//! \~english Returns the message body.
	//! \~russian Возвращает тело сообщения.
	const PIByteArray & body() const { return m_payload; }

	//! \~english Returns the message body.
	//! \~russian Возвращает тело сообщения.
	const PIByteArray & payload() const { return m_payload; }

	//! \~english Returns extracted path arguments.
	//! \~russian Возвращает извлеченные аргументы пути.
	const PIMap<PIString, PIString> & pathArguments() const { return m_path_arguments; }

	//! \~english Returns map of properties.
	//! \~russian Возвращает карту свойств.
	const PIMap<int, PIString> & properties() const { return m_properties; }


	//! \~english Returns \c true for .
	//! \~russian Возвращает \c true для .
	bool isDuplicate() const { return m_is_duplicate; }

	//! \~english Returns QoS.
	//! \~russian Возвращает QoS.
	QoS qos() const { return m_qos; }

	//! \~english Returns message ID.
	//! \~russian Возвращает ID сообщения.
	int ID() const { return m_msg_id; }

protected:
	PIString m_topic;
	PIMap<PIString, PIString> m_path_arguments;
	PIByteArray m_payload;
	PIMap<int, PIString> m_properties; // for v5
	QoS m_qos           = QoS::Level0;
	int m_msg_id        = 0;
	bool m_is_duplicate = false;
};


//! \~\ingroup MQTT
//! \~\brief
//! \~english Mutable MQTT message.
//! \~russian Изменяемое MQTT-сообщение.
class PIP_EXPORT MessageMutable: public MessageConst {
public:
	//! \~english Sets the topic.
	//! \~russian Устанавливает топик.
	MessageMutable & setTopic(PIString t);

	//! \~english Sets the message body.
	//! \~russian Устанавливает тело сообщения.
	MessageMutable & setBody(PIByteArray b);

	//! \~english Sets the message body.
	//! \~russian Устанавливает тело сообщения.
	MessageMutable & setPayload(PIByteArray b) { return setBody(b); }


	//! \~english Returns path arguments.
	//! \~russian Возвращает аргументы пути.
	const PIMap<PIString, PIString> & pathArguments() const { return m_path_arguments; }

	//! \~english Returns a modifiable map of path arguments.
	//! \~russian Возвращает изменяемую карту аргументов пути.
	PIMap<PIString, PIString> & pathArguments() { return m_path_arguments; }


	//! \~english Returns map of properties.
	//! \~russian Возвращает карту свойств.
	const PIMap<int, PIString> & properties() const { return m_properties; }

	//! \~english Returns a modifiable map of properties.
	//! \~russian Возвращает изменяемую карту свойств.
	PIMap<int, PIString> & properties() { return m_properties; }


	//! \~english Returns \c true for .
	//! \~russian Возвращает \c true для .
	MessageMutable & setDuplicate(bool yes);

	//! \~english Returns QoS.
	//! \~russian Возвращает QoS.
	MessageMutable & setQos(QoS qos);

	//! \~english Returns message ID.
	//! \~russian Возвращает ID сообщения.
	MessageMutable & setID(int id);
};


}; // namespace PIMQTT


#endif
