/*
 * Copyright (C) 2014-2024 CZ.NIC
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

#include <QDate>
#include <QString>
#include <utility> /* ::std::move */

#include "src/datovka_shared/isds/box_interface2.h" /* PersonName2 */
#include "src/datovka_shared/isds/message_interface2.h"

/* Null objects - for convenience. */
static const Isds::DmMessageAuthor nullDmMessageAuthor;
static const Isds::PersonName2 nullPersonName2;
static const QDate nullDate;
static const QString nullString;

#define DFLT_USER_TYPE Type::ST_NULL
#define DFLT_ROB_IDENT Type::BOOL_NULL

/*!
 * @brief PIMPL DmMessageAuthor class.
 */
class Isds::DmMessageAuthorPrivate {
	//Q_DISABLE_COPY(DmMessageAuthorPrivate)
public:
	DmMessageAuthorPrivate(void)
	    : m_userType(DFLT_USER_TYPE), m_personName(), m_biDate(),
	    m_biCity(), m_biCounty(), m_adCode(), m_fullAddress(),
	    m_robIdent(DFLT_ROB_IDENT)
	{ }

	DmMessageAuthorPrivate &operator=(const DmMessageAuthorPrivate &other) Q_DECL_NOTHROW
	{
		m_userType = other.m_userType;
		m_personName = other.m_personName;
		m_biDate = other.m_biDate;
		m_biCity = other.m_biCity;
		m_biCounty = other.m_biCounty;
		m_adCode = other.m_adCode;
		m_fullAddress = other.m_fullAddress;
		m_robIdent = other.m_robIdent;

		return *this;
	}

	bool operator==(const DmMessageAuthorPrivate &other) const
	{
		return (m_userType == other.m_userType) &&
		    (m_personName == other.m_personName) &&
		    (m_biDate == other.m_biDate) &&
		    (m_biCity == other.m_biCity) &&
		    (m_biCounty == other.m_biCounty) &&
		    (m_adCode == other.m_adCode) &&
		    (m_fullAddress == other.m_fullAddress) &&
		    (m_robIdent == other.m_robIdent);
	}


	enum Type::SenderType m_userType;
	PersonName2 m_personName;
	QDate m_biDate;
	QString m_biCity;
	QString m_biCounty;
	QString m_adCode;
	QString m_fullAddress;
	enum Type::NilBool m_robIdent;
};

Isds::DmMessageAuthor::DmMessageAuthor(void)
    : d_ptr(Q_NULLPTR)
{
}

Isds::DmMessageAuthor::DmMessageAuthor(const DmMessageAuthor &other)
    : d_ptr((other.d_func() != Q_NULLPTR) ? (new (::std::nothrow) DmMessageAuthorPrivate) : Q_NULLPTR)
{
	Q_D(DmMessageAuthor);
	if (d == Q_NULLPTR) {
		return;
	}

	*d = *other.d_func();
}

#ifdef Q_COMPILER_RVALUE_REFS
Isds::DmMessageAuthor::DmMessageAuthor(DmMessageAuthor &&other) Q_DECL_NOEXCEPT
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
    : d_ptr(other.d_ptr.release()) //d_ptr(::std::move(other.d_ptr))
#else /* < Qt-5.12 */
    : d_ptr(other.d_ptr.take())
#endif /* >= Qt-5.12 */
{
}
#endif /* Q_COMPILER_RVALUE_REFS */

Isds::DmMessageAuthor::~DmMessageAuthor(void)
{
}

/*!
 * @brief Ensures DmMessageAuthorPrivate presence.
 *
 * @note Returns if DmMessageAuthorPrivate could not be allocated.
 */
#define ensureDmMessageAuthorPrivate(_x_) \
	do { \
		if (Q_UNLIKELY(d_ptr == Q_NULLPTR)) { \
			DmMessageAuthorPrivate *p = new (::std::nothrow) DmMessageAuthorPrivate; \
			if (Q_UNLIKELY(p == Q_NULLPTR)) { \
				Q_ASSERT(0); \
				return _x_; \
			} \
			d_ptr.reset(p); \
		} \
	} while (0)

Isds::DmMessageAuthor &Isds::DmMessageAuthor::operator=(const DmMessageAuthor &other) Q_DECL_NOTHROW
{
	if (other.d_func() == Q_NULLPTR) {
		d_ptr.reset(Q_NULLPTR);
		return *this;
	}
	ensureDmMessageAuthorPrivate(*this);
	Q_D(DmMessageAuthor);

	*d = *other.d_func();

	return *this;
}

#ifdef Q_COMPILER_RVALUE_REFS
Isds::DmMessageAuthor &Isds::DmMessageAuthor::operator=(DmMessageAuthor &&other) Q_DECL_NOTHROW
{
	swap(*this, other);
	return *this;
}
#endif /* Q_COMPILER_RVALUE_REFS */

bool Isds::DmMessageAuthor::operator==(const DmMessageAuthor &other) const
{
	Q_D(const DmMessageAuthor);
	if ((d == Q_NULLPTR) && ((other.d_func() == Q_NULLPTR))) {
		return true;
	} else if ((d == Q_NULLPTR) || ((other.d_func() == Q_NULLPTR))) {
		return false;
	}

	return *d == *other.d_func();
}

bool Isds::DmMessageAuthor::operator!=(const DmMessageAuthor &other) const
{
	return !operator==(other);
}

bool Isds::DmMessageAuthor::isNull(void) const
{
	Q_D(const DmMessageAuthor);
	return d == Q_NULLPTR;
}

enum Isds::Type::SenderType Isds::DmMessageAuthor::userType(void) const
{
	Q_D(const DmMessageAuthor);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_USER_TYPE;
	}

	return d->m_userType;
}

void Isds::DmMessageAuthor::setUserType(enum Type::SenderType ut)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_userType = ut;
}

const Isds::PersonName2 &Isds::DmMessageAuthor::personName(void) const
{
	Q_D(const DmMessageAuthor);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullPersonName2;
	}

	return d->m_personName;
}

void Isds::DmMessageAuthor::setPersonName(const PersonName2 &pn)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_personName = pn;
}

#ifdef Q_COMPILER_RVALUE_REFS
void Isds::DmMessageAuthor::setPersonName(PersonName2 &&pn)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_personName = ::std::move(pn);
}
#endif /* Q_COMPILER_RVALUE_REFS */

const QDate &Isds::DmMessageAuthor::biDate(void) const
{
	Q_D(const DmMessageAuthor);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullDate;
	}

	return d->m_biDate;
}

void Isds::DmMessageAuthor::setBiDate(const QDate &bd)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_biDate = bd;
}

#ifdef Q_COMPILER_RVALUE_REFS
void Isds::DmMessageAuthor::setBiDate(QDate &&bd)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_biDate = ::std::move(bd);
}
#endif /* Q_COMPILER_RVALUE_REFS */

const QString &Isds::DmMessageAuthor::biCity(void) const
{
	Q_D(const DmMessageAuthor);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullString;
	}

	return d->m_biCity;
}

void Isds::DmMessageAuthor::setBiCity(const QString &bc)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_biCity = bc;
}

#ifdef Q_COMPILER_RVALUE_REFS
void Isds::DmMessageAuthor::setBiCity(QString &&bc)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_biCity = ::std::move(bc);
}
#endif /* Q_COMPILER_RVALUE_REFS */

const QString &Isds::DmMessageAuthor::biCounty(void) const
{
	Q_D(const DmMessageAuthor);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullString;
	}

	return d->m_biCounty;
}

void Isds::DmMessageAuthor::setBiCounty(const QString &bc)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_biCounty = bc;
}

#ifdef Q_COMPILER_RVALUE_REFS
void Isds::DmMessageAuthor::setBiCounty(QString &&bc)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_biCounty = ::std::move(bc);
}
#endif /* Q_COMPILER_RVALUE_REFS */

const QString &Isds::DmMessageAuthor::adCode(void) const
{
	Q_D(const DmMessageAuthor);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullString;
	}

	return d->m_adCode;
}

void Isds::DmMessageAuthor::setAdCode(const QString &ac)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_adCode = ac;
}

#ifdef Q_COMPILER_RVALUE_REFS
void Isds::DmMessageAuthor::setAdCode(QString &&ac)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_adCode = ::std::move(ac);
}
#endif /* Q_COMPILER_RVALUE_REFS */

const QString &Isds::DmMessageAuthor::fullAddress(void) const
{
	Q_D(const DmMessageAuthor);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullString;
	}

	return d->m_fullAddress;
}

void Isds::DmMessageAuthor::setFullAddress(const QString &fa)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_fullAddress = fa;
}

#ifdef Q_COMPILER_RVALUE_REFS
void Isds::DmMessageAuthor::setFullAddress(QString &&fa)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_fullAddress = ::std::move(fa);
}
#endif /* Q_COMPILER_RVALUE_REFS */

enum Isds::Type::NilBool Isds::DmMessageAuthor::robIdent(void) const
{
	Q_D(const DmMessageAuthor);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_ROB_IDENT;
	}

	return d->m_robIdent;
}

void Isds::DmMessageAuthor::setRobIdent(enum Type::NilBool ri)
{
	ensureDmMessageAuthorPrivate();
	Q_D(DmMessageAuthor);
	d->m_robIdent = ri;
}

void Isds::swap(DmMessageAuthor &first, DmMessageAuthor &second) Q_DECL_NOTHROW
{
	using ::std::swap;
	swap(first.d_ptr, second.d_ptr);
}
