/*
 * Copyright (C) 2014-2022 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 <QDateTime>
#include <QJsonObject>
#include <QJsonValue>
#include <QString>
#include <utility> /* ::std::swap */

#include "src/datovka_shared/json/helper.h"
#include "src/datovka_shared/records_management/json/entry_error.h"
#include "src/datovka_shared/records_management/json/upload_account_status.h"

#ifdef Q_COMPILER_RVALUE_REFS
#  define macroStdMove(x) ::std::move(x)
#else /* Q_COMPILER_RVALUE_REFS */
#  define macroStdMove(x) (x)
#endif /* Q_COMPILER_RVALUE_REFS */

/* Null objects - for convenience. */
#define NULL_INT -1
static const QString nullString;
static const QDateTime nullDateTime;
static const RecMgmt::ErrorEntry nullErrorEntry;

static
const QString keyBoxId("box_id");
static
const QString keyUserId("user_id");
static
const QString keyTime("time");
static
const QString keyDmCntRcvdNotAccepted("dm_cnt_rcvd_not_accepted");
static
const QString keyDmCntSntNotAccepted("dm_cnt_snt_not_accepted");
static
const QString keyDmCntRcvdNotInRm("dm_cnt_rcvd_not_in_rm");
static
const QString keyDmCntSntNotInRm("dm_cnt_snt_not_in_rm");
static
const QString keyUserAccountName("user_account_name");

static
const QString keyError("error");

class RecMgmt::UploadAccountStatusReqPrivate {
public:
	UploadAccountStatusReqPrivate(void)
	    : m_boxId(), m_userId(), m_time(), m_rcvdNotAccepted(NULL_INT),
	    m_sntNotAccepted(NULL_INT), m_rcvdNotInRecMgmt(NULL_INT),
	    m_sntNotInRecMgmt(NULL_INT), m_userAccountName()
	{ }

	UploadAccountStatusReqPrivate &operator=(const UploadAccountStatusReqPrivate &other) Q_DECL_NOTHROW
	{
		m_boxId = other.m_boxId;
		m_userId = other.m_userId;
		m_time = other.m_time;
		m_rcvdNotAccepted = other.m_rcvdNotAccepted;
		m_sntNotAccepted = other.m_sntNotAccepted;
		m_rcvdNotInRecMgmt = other.m_rcvdNotInRecMgmt;
		m_sntNotInRecMgmt = other.m_sntNotInRecMgmt;
		m_userAccountName = other.m_userAccountName;

		return *this;
	}

	bool operator==(const UploadAccountStatusReqPrivate &other) const
	{
		return (m_boxId == other.m_boxId) &&
		    (m_userId == other.m_userId) &&
		    (m_time == other.m_time) &&
		    (m_rcvdNotAccepted == other.m_rcvdNotAccepted) &&
		    (m_sntNotAccepted == other.m_sntNotAccepted) &&
		    (m_rcvdNotInRecMgmt == other.m_rcvdNotInRecMgmt) &&
		    (m_sntNotInRecMgmt == other.m_sntNotInRecMgmt) &&
		    (m_userAccountName == other.m_userAccountName);
	}

	QString m_boxId; /*!< Data box identifier. */
	QString m_userId; /*!< Username used to access the data box. */
	QDateTime m_time; /*!< Time. */
	int m_rcvdNotAccepted; /*!< Number of received unaccepted messages in box. */
	int m_sntNotAccepted; /*!< Number of sent unaccepted messages in box. */
	int m_rcvdNotInRecMgmt; /*!< Number of received messages not sent into records management. */
	int m_sntNotInRecMgmt; /*!< Number of sent messages not sent into records management. */
	QString m_userAccountName; /*!< User-defined account identifier as used in the application. */
};

RecMgmt::UploadAccountStatusReq::UploadAccountStatusReq(void)
    : Json::Object(),
    d_ptr(Q_NULLPTR)
{
}

RecMgmt::UploadAccountStatusReq::UploadAccountStatusReq(
    const UploadAccountStatusReq &other)
    : Json::Object(),
    d_ptr((other.d_func() != Q_NULLPTR) ? (new (::std::nothrow) UploadAccountStatusReqPrivate) : Q_NULLPTR)
{
	Q_D(UploadAccountStatusReq);
	if (d == Q_NULLPTR) {
		return;
	}

	*d = *other.d_func();
}

#ifdef Q_COMPILER_RVALUE_REFS
RecMgmt::UploadAccountStatusReq::UploadAccountStatusReq(UploadAccountStatusReq &&other) Q_DECL_NOEXCEPT
    : Json::Object(),
#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 */

RecMgmt::UploadAccountStatusReq::~UploadAccountStatusReq(void)
{
}

RecMgmt::UploadAccountStatusReq::UploadAccountStatusReq(const QString &boxId,
    const QString &userId, const QDateTime &time, int rcvdNotAccepted,
    int sntNotAccepted, int rcvdNotInRecMgmt, int sntNotInRecMgmt,
    const QString &userAccountName)
    : Json::Object(),
    d_ptr(new (::std::nothrow) UploadAccountStatusReqPrivate)
{
	Q_D(UploadAccountStatusReq);
	d->m_boxId = boxId;
	d->m_userId = userId;
	d->m_time = time;
	d->m_rcvdNotAccepted = rcvdNotAccepted;
	d->m_sntNotAccepted = sntNotAccepted;
	d->m_rcvdNotInRecMgmt = rcvdNotInRecMgmt;
	d->m_sntNotInRecMgmt = sntNotInRecMgmt;
	d->m_userAccountName = userAccountName;
}

#ifdef Q_COMPILER_RVALUE_REFS
RecMgmt::UploadAccountStatusReq::UploadAccountStatusReq(QString &&boxId,
    QString &&userId, QDateTime &&time, int rcvdNotAccepted, int sntNotAccepted,
    int rcvdNotInRecMgmt, int sntNotInRecMgmt, QString &&userAccountName)
    : Json::Object(),
    d_ptr(new (::std::nothrow) UploadAccountStatusReqPrivate)
{
	Q_D(UploadAccountStatusReq);
	d->m_boxId = ::std::move(boxId);
	d->m_userId = ::std::move(userId);
	d->m_time = ::std::move(time);
	d->m_rcvdNotAccepted = rcvdNotAccepted;
	d->m_sntNotAccepted = sntNotAccepted;
	d->m_rcvdNotInRecMgmt = rcvdNotInRecMgmt;
	d->m_sntNotInRecMgmt = sntNotInRecMgmt;
	d->m_userAccountName = ::std::move(userAccountName);
}
#endif /* Q_COMPILER_RVALUE_REFS */

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

RecMgmt::UploadAccountStatusReq &RecMgmt::UploadAccountStatusReq::operator=(const UploadAccountStatusReq &other) Q_DECL_NOTHROW
{
	if (other.d_func() == Q_NULLPTR) {
		d_ptr.reset(Q_NULLPTR);
		return *this;
	}
	ensureUploadAccountStatusReqPrivate(*this);
	Q_D(UploadAccountStatusReq);

	*d = *other.d_func();

	return *this;
}

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

bool RecMgmt::UploadAccountStatusReq::operator==(const UploadAccountStatusReq &other) const
{
	Q_D(const UploadAccountStatusReq);
	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 RecMgmt::UploadAccountStatusReq::operator!=(const UploadAccountStatusReq &other) const
{
	return !operator==(other);
}

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

bool RecMgmt::UploadAccountStatusReq::isNull(void) const
{
	Q_D(const UploadAccountStatusReq);
	return d == Q_NULLPTR;
}

bool RecMgmt::UploadAccountStatusReq::isValid(void) const
{
	Q_D(const UploadAccountStatusReq);
	return (!isNull()) && (!d->m_boxId.isEmpty()) &&
	    (!d->m_userId.isEmpty()) && d->m_time.isValid() &&
	    (d->m_rcvdNotAccepted >= 0) && (d->m_sntNotAccepted >= 0) &&
	    (d->m_rcvdNotInRecMgmt >= 0) && (d->m_sntNotInRecMgmt >= 0);
	/* User account name may be null. */
}

const QString &RecMgmt::UploadAccountStatusReq::boxId(void) const
{
	Q_D(const UploadAccountStatusReq);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullString;
	}

	return d->m_boxId;
}

void RecMgmt::UploadAccountStatusReq::setBoxId(const QString &b)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_boxId = b;
}

#ifdef Q_COMPILER_RVALUE_REFS
void RecMgmt::UploadAccountStatusReq::setBoxId(QString &&b)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_boxId = ::std::move(b);
}
#endif /* Q_COMPILER_RVALUE_REFS */

const QString &RecMgmt::UploadAccountStatusReq::userId(void) const
{
	Q_D(const UploadAccountStatusReq);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullString;
	}

	return d->m_userId;
}

void RecMgmt::UploadAccountStatusReq::setUserId(const QString &u)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_userId = u;
}

#ifdef Q_COMPILER_RVALUE_REFS
void RecMgmt::UploadAccountStatusReq::setUserId(QString &&u)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_userId = ::std::move(u);
}
#endif /* Q_COMPILER_RVALUE_REFS */

const QDateTime &RecMgmt::UploadAccountStatusReq::time(void) const
{
	Q_D(const UploadAccountStatusReq);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullDateTime;
	}

	return d->m_time;
}

void RecMgmt::UploadAccountStatusReq::setTime(const QDateTime &t)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_time = t;
}

#ifdef Q_COMPILER_RVALUE_REFS
void RecMgmt::UploadAccountStatusReq::setTime(QDateTime &&t)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_time = ::std::move(t);
}
#endif /* Q_COMPILER_RVALUE_REFS */

int RecMgmt::UploadAccountStatusReq::rcvdNotAccepted(void) const
{
	Q_D(const UploadAccountStatusReq);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return NULL_INT;
	}

	return d->m_rcvdNotAccepted;
}

void RecMgmt::UploadAccountStatusReq::setRcvdNotAccepted(int rna)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_rcvdNotAccepted = rna;
}

int RecMgmt::UploadAccountStatusReq::sntNotAccepted(void) const
{
	Q_D(const UploadAccountStatusReq);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return NULL_INT;
	}

	return d->m_sntNotAccepted;
}

void RecMgmt::UploadAccountStatusReq::setSntNotAccepted(int sna)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_sntNotAccepted = sna;
}

int RecMgmt::UploadAccountStatusReq::rcvdNotInRecMgmt(void) const
{
	Q_D(const UploadAccountStatusReq);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return NULL_INT;
	}

	return d->m_rcvdNotInRecMgmt;
}

void RecMgmt::UploadAccountStatusReq::setRcvdNotInRecMgmt(int rni)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_rcvdNotInRecMgmt = rni;
}

int RecMgmt::UploadAccountStatusReq::sntNotInRecMgmt(void) const
{
	Q_D(const UploadAccountStatusReq);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return NULL_INT;
	}

	return d->m_sntNotInRecMgmt;
}

void RecMgmt::UploadAccountStatusReq::setSntNotInRecMgmt(int sni)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_sntNotInRecMgmt = sni;
}

const QString &RecMgmt::UploadAccountStatusReq::userAccountName(void) const
{
	Q_D(const UploadAccountStatusReq);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullString;
	}

	return d->m_userAccountName;
}

void RecMgmt::UploadAccountStatusReq::setUserAccountName(const QString &ua)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_userAccountName = ua;
}

#ifdef Q_COMPILER_RVALUE_REFS
void RecMgmt::UploadAccountStatusReq::setUserAccountName(QString &&ua)
{
	ensureUploadAccountStatusReqPrivate();
	Q_D(UploadAccountStatusReq);
	d->m_userAccountName = ::std::move(ua);
}
#endif /* Q_COMPILER_RVALUE_REFS */

RecMgmt::UploadAccountStatusReq RecMgmt::UploadAccountStatusReq::fromJson(
    const QByteArray &json, bool *ok)
{
	QJsonObject jsonObj;
	if (Q_UNLIKELY(!Json::Helper::readRootObject(json, jsonObj))) {
		if (ok != Q_NULLPTR) {
			*ok = false;
		}
		return UploadAccountStatusReq();
	}

	return fromJsonVal(jsonObj, ok);
}

RecMgmt::UploadAccountStatusReq RecMgmt::UploadAccountStatusReq::fromJsonVal(
    const QJsonValue &jsonVal, bool *ok)
{
	UploadAccountStatusReq uasr;

	if (Q_UNLIKELY(!jsonVal.isObject())) {
		goto fail;
	}

	{
		const QJsonObject jsonObj = jsonVal.toObject();
		{
			QString valStr;
			if (Json::Helper::readString(jsonObj, keyBoxId, valStr,
			        Json::Helper::ACCEPT_NULL)) {
				uasr.setBoxId(macroStdMove(valStr));
			} else {
				goto fail;
			}
		}
		{
			QString valStr;
			if (Json::Helper::readString(jsonObj, keyUserId, valStr,
			        Json::Helper::ACCEPT_NULL)) {
				uasr.setUserId(macroStdMove(valStr));
			} else {
				goto fail;
			}
		}
		{
			QDateTime valDateTime;
			if (Json::Helper::readQDateTimeString(jsonObj, keyTime, valDateTime,
			        Json::Helper::ACCEPT_NULL)) {
				uasr.setTime(macroStdMove(valDateTime));
			} else {
				goto fail;
			}
		}
		{
			int valInt = NULL_INT;
			if (Json::Helper::readInt(jsonObj, keyDmCntRcvdNotAccepted,
			        valInt, Json::Helper::ACCEPT_NULL)) {
				uasr.setRcvdNotAccepted(valInt);
			} else {
				goto fail;
			}
		}
		{
			int valInt = NULL_INT;
			if (Json::Helper::readInt(jsonObj, keyDmCntSntNotAccepted,
			        valInt, Json::Helper::ACCEPT_NULL)) {
				uasr.setSntNotAccepted(valInt);
			} else {
				goto fail;
			}
		}
		{
			int valInt = NULL_INT;
			if (Json::Helper::readInt(jsonObj, keyDmCntRcvdNotInRm,
			        valInt, Json::Helper::ACCEPT_NULL)) {
				uasr.setRcvdNotInRecMgmt(valInt);
			} else {
				goto fail;
			}
		}
		{
			int valInt = NULL_INT;
			if (Json::Helper::readInt(jsonObj, keyDmCntSntNotInRm,
			        valInt, Json::Helper::ACCEPT_NULL)) {
				uasr.setSntNotInRecMgmt(valInt);
			} else {
				goto fail;
			}
		}
		{
			QString valStr;
			if (Json::Helper::readString(jsonObj, keyUserAccountName,
			        valStr, Json::Helper::ACCEPT_NULL)) {
				uasr.setUserAccountName(macroStdMove(valStr));
			} else {
				goto fail;
			}
		}

		if (ok != Q_NULLPTR) {
			*ok = true;
		}
		return uasr;
	}

fail:
	if (ok != Q_NULLPTR) {
		*ok = false;
	}
	return UploadAccountStatusReq();
}

bool RecMgmt::UploadAccountStatusReq::toJsonVal(QJsonValue &jsonVal) const
{
	QJsonObject jsonObj;

	jsonObj.insert(keyBoxId, !boxId().isNull() ? boxId() : QJsonValue());
	jsonObj.insert(keyUserId, !userId().isNull() ? userId() : QJsonValue());
	/*
	 * Intentionally using UTC because Qt gets a bit schizophrenic when
	 * generating ISO 8601 formatted time strings:
	 * https://stackoverflow.com/q/21976264
	 *
	 * m_time.toOffsetFromUtc(m_time.offsetFromUtc()).toString(Qt::ISODate)
	 */
	jsonObj.insert(keyTime,
	    time().isValid() ? time().toUTC().toString(Qt::ISODate) : QJsonValue());
	jsonObj.insert(keyDmCntRcvdNotAccepted,
	    (rcvdNotAccepted() >= 0) ? rcvdNotAccepted() : QJsonValue());
	jsonObj.insert(keyDmCntSntNotAccepted,
	    (sntNotAccepted() >= 0) ? sntNotAccepted() : QJsonValue());
	jsonObj.insert(keyDmCntRcvdNotInRm,
	    (rcvdNotInRecMgmt() >= 0) ? rcvdNotInRecMgmt() : QJsonValue());
	jsonObj.insert(keyDmCntSntNotInRm,
	    (sntNotInRecMgmt() >= 0) ? sntNotInRecMgmt() : QJsonValue());
	jsonObj.insert(keyUserAccountName,
	    !userAccountName().isNull() ? userAccountName() : QJsonValue());

	jsonVal = jsonObj;
	return true;
}

class RecMgmt::UploadAccountStatusRespPrivate {
public:
	UploadAccountStatusRespPrivate(void)
	    : m_error()
	{ }

	UploadAccountStatusRespPrivate &operator=(const UploadAccountStatusRespPrivate &other) Q_DECL_NOTHROW
	{
		m_error = other.m_error;

		return *this;
	}

	bool operator==(const UploadAccountStatusRespPrivate &other) const
	{
		return (m_error == other.m_error);
	}

	ErrorEntry m_error; /*!< Error entry. */
};

RecMgmt::UploadAccountStatusResp::UploadAccountStatusResp(void)
    : Json::Object(),
    d_ptr(Q_NULLPTR)
{
}

RecMgmt::UploadAccountStatusResp::UploadAccountStatusResp(const UploadAccountStatusResp &other)
    : Json::Object(),
    d_ptr((other.d_func() != Q_NULLPTR) ? (new (::std::nothrow) UploadAccountStatusRespPrivate) : Q_NULLPTR)
{
	Q_D(UploadAccountStatusResp);
	if (d == Q_NULLPTR) {
		return;
	}

	*d = *other.d_func();
}

#ifdef Q_COMPILER_RVALUE_REFS
RecMgmt::UploadAccountStatusResp::UploadAccountStatusResp(UploadAccountStatusResp &&other) Q_DECL_NOEXCEPT
    : Json::Object(),
#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 */

RecMgmt::UploadAccountStatusResp::~UploadAccountStatusResp(void)
{
}

RecMgmt::UploadAccountStatusResp::UploadAccountStatusResp(const ErrorEntry &error)
    : Json::Object(),
    d_ptr(new (::std::nothrow) UploadAccountStatusRespPrivate)
{
	Q_D(UploadAccountStatusResp);
	d->m_error = error;
}

#ifdef Q_COMPILER_RVALUE_REFS
RecMgmt::UploadAccountStatusResp::UploadAccountStatusResp(ErrorEntry &&error)
    : Json::Object(),
    d_ptr(new (::std::nothrow) UploadAccountStatusRespPrivate)
{
	Q_D(UploadAccountStatusResp);
	d->m_error = ::std::move(error);
}
#endif /* Q_COMPILER_RVALUE_REFS */

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

RecMgmt::UploadAccountStatusResp &RecMgmt::UploadAccountStatusResp::operator=(const UploadAccountStatusResp &other) Q_DECL_NOTHROW
{
	if (other.d_func() == Q_NULLPTR) {
		d_ptr.reset(Q_NULLPTR);
		return *this;
	}
	ensureUploadAccountStatusRespPrivate(*this);
	Q_D(UploadAccountStatusResp);

	*d = *other.d_func();

	return *this;
}

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

bool RecMgmt::UploadAccountStatusResp::operator==(const UploadAccountStatusResp &other) const
{
	Q_D(const UploadAccountStatusResp);
	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 RecMgmt::UploadAccountStatusResp::operator!=(const UploadAccountStatusResp &other) const
{
	return !operator==(other);
}

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

bool RecMgmt::UploadAccountStatusResp::isNull(void) const
{
	Q_D(const UploadAccountStatusResp);
	return d == Q_NULLPTR;
}

bool RecMgmt::UploadAccountStatusResp::isValid(void) const
{
	return true; /* Any value is valid. */
}

const RecMgmt::ErrorEntry &RecMgmt::UploadAccountStatusResp::error(void) const
{
	Q_D(const UploadAccountStatusResp);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullErrorEntry;
	}

	return d->m_error;
}

void RecMgmt::UploadAccountStatusResp::setError(const ErrorEntry &e)
{
	ensureUploadAccountStatusRespPrivate();
	Q_D(UploadAccountStatusResp);
	d->m_error = e;
}

#ifdef Q_COMPILER_RVALUE_REFS
void RecMgmt::UploadAccountStatusResp::setError(ErrorEntry &&e)
{
	ensureUploadAccountStatusRespPrivate();
	Q_D(UploadAccountStatusResp);
	d->m_error = ::std::move(e);
}
#endif /* Q_COMPILER_RVALUE_REFS */

RecMgmt::UploadAccountStatusResp RecMgmt::UploadAccountStatusResp::fromJson(
    const QByteArray &json, bool *ok)
{
	QJsonObject jsonObj;
	if (Q_UNLIKELY(!Json::Helper::readRootObject(json, jsonObj))) {
		if (ok != Q_NULLPTR) {
			*ok = false;
		}
		return UploadAccountStatusResp();
	}

	return fromJsonVal(jsonObj, ok);
}

RecMgmt::UploadAccountStatusResp RecMgmt::UploadAccountStatusResp::fromJsonVal(
    const QJsonValue &jsonVal, bool *ok)
{
	UploadAccountStatusResp uasr;

	if (Q_UNLIKELY(!jsonVal.isObject())) {
		goto fail;
	}

	{
		const QJsonObject jsonObj = jsonVal.toObject();
		{
			QJsonValue jsonVal;
			if (Json::Helper::readValue(jsonObj, keyError, jsonVal,
			        Json::Helper::ACCEPT_NULL)) {
				bool iOk = false;
				uasr.setError(ErrorEntry::fromJsonVal(jsonVal, &iOk));
				if (Q_UNLIKELY(!iOk)) {
					goto fail;
				}
			} else {
				goto fail;
			}
		}

		if (ok != Q_NULLPTR) {
			*ok = true;
		}
		return uasr;
	}

fail:
	if (ok != Q_NULLPTR) {
		*ok = false;
	}
	return UploadAccountStatusResp();
}

bool RecMgmt::UploadAccountStatusResp::toJsonVal(QJsonValue &jsonVal) const
{
	QJsonObject jsonObj;

	{
		QJsonValue jsonVal;
		if (Q_UNLIKELY(!error().toJsonVal(jsonVal))) {
			goto fail;
		}
		jsonObj.insert(keyError, jsonVal);
	}

	jsonVal = jsonObj;
	return true;

fail:
	jsonVal = QJsonObject();
	return false;
}
