/*
 * 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 <QJsonObject>
#include <QString>
#include <QSysInfo>

#include "src/datovka_shared/json/report.h"

/* Null objects - for convenience. */
static const QString nullString;

#define DFLT_APP_TYPE Json::Report::AT_UNKNOWN
#define DFLT_BOOL_VAL false
#define DFLT_INT_VAL -1

#define REPORT_VER "0"

/* Keep keys as short as possible. */
static const QString keyReportVersion("v");
static const QString keyAppType("at");

static const QString keyUniqueId("mui");
static const QString keyQtCompileVersion("qcv"); 
static const QString keyQtRuntimeVersion("qrv");
static const QString keyBuildCpuArchitecture("bca");
static const QString keyRuntimeCpuArchitecture("rca");
static const QString keyPretyProductName("ppn");

static const QString keyAppVersion("av");
static const QString keyConfPortableApp("port");
static const QString keyConfTags("tags");
static const QString keyBundedQuazip("bqz");

static const QString keyNumBoxesProd("nbp");
static const QString keyNumBoxesTesting("nbt");
static const QString keyMessageDataSizeProd("mdsp");
static const QString keyMessageDataSizeTesting("mdst");
static const QString keyNumDefinedTags("ndt");
static const QString keyUsesDatabasesInMemory("udim");
static const QString keyUsesPin("up");
static const QString keyUsesRecordsManagement("urm");

class Json::BuildReportPrivate {
public:
	BuildReportPrivate(void)
	    : m_appType(DFLT_APP_TYPE), m_uniqueId()
	{ }

	BuildReportPrivate &operator=(const BuildReportPrivate &other) Q_DECL_NOTHROW
	{
		m_appType = other.m_appType;
		m_uniqueId = other.m_uniqueId;

		return *this;
	}

	bool operator==(const BuildReportPrivate &other) const
	{
		return (m_appType == other.m_appType) &&
		    (m_uniqueId == other.m_uniqueId);
	}

	enum Report::AppType m_appType;
	QString m_uniqueId;
};

Json::BuildReport::BuildReport(void)
    : Object(),
    d_ptr(Q_NULLPTR)
{
}

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

	*d = *other.d_func();
}

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

Json::BuildReport::~BuildReport(void)
{
}

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

Json::BuildReport &Json::BuildReport::operator=(const BuildReport &other) Q_DECL_NOTHROW
{
	if (other.d_func() == Q_NULLPTR) {
		d_ptr.reset(Q_NULLPTR);
		return *this;
	}
	ensureBuildReportPrivate(*this);
	Q_D(BuildReport);

	*d = *other.d_func();

	return *this;
}

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

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

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

bool Json::BuildReport::isNull(void) const
{
	Q_D(const BuildReport);
	return d == Q_NULLPTR;
}

bool Json::BuildReport::isValid(void) const
{
	Q_D(const BuildReport);
	return (!isNull()) && (!d->m_uniqueId.isEmpty());
}

enum Json::Report::AppType Json::BuildReport::appType(void) const
{
	Q_D(const BuildReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_APP_TYPE;
	}

	return d->m_appType;
}

void Json::BuildReport::setAppType(enum Report::AppType at)
{
	ensureBuildReportPrivate();
	Q_D(BuildReport);
	d->m_appType = at;
}

const QString &Json::BuildReport::uniqueId(void) const
{
	Q_D(const BuildReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullString;
	}

	return d->m_uniqueId;
}

void Json::BuildReport::setUniqueId(const QString &ui)
{
	ensureBuildReportPrivate();
	Q_D(BuildReport);
	d->m_uniqueId = ui;
}

#ifdef Q_COMPILER_RVALUE_REFS
void Json::BuildReport::setUniqueId(QString &&ui)
{
	ensureBuildReportPrivate();
	Q_D(BuildReport);
	d->m_uniqueId = ::std::move(ui);
}
#endif /* Q_COMPILER_RVALUE_REFS */

bool Json::BuildReport::toJsonVal(QJsonValue &jsonVal) const
{
	QJsonObject jsonObj;

	jsonObj.insert(keyReportVersion, QString(REPORT_VER)); /* value QString */

	if (appType() != Report::AT_UNKNOWN) {
		jsonObj.insert(keyAppType, (int)appType());
	}
	if (!uniqueId().isEmpty()) {
		jsonObj.insert(keyUniqueId, uniqueId());
	}

	jsonObj.insert(keyQtCompileVersion, QString(QT_VERSION_STR)); /* value QString */
	jsonObj.insert(keyQtRuntimeVersion, QString(qVersion())); /* value QString */

#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
	jsonObj.insert(keyBuildCpuArchitecture, QSysInfo::buildCpuArchitecture());
	jsonObj.insert(keyRuntimeCpuArchitecture, QSysInfo::currentCpuArchitecture());
	jsonObj.insert(keyPretyProductName, QSysInfo::prettyProductName());
#endif /* >= Qt-5.4 */

	jsonVal = jsonObj;
	return true;
}

class Json::ConfReportPrivate {
public:
	ConfReportPrivate(void)
	    : m_appType(DFLT_APP_TYPE), m_uniqueId()
	{ }

	ConfReportPrivate &operator=(const ConfReportPrivate &other) Q_DECL_NOTHROW
	{
		m_appType = other.m_appType;
		m_uniqueId = other.m_uniqueId;

		return *this;
	}

	bool operator==(const ConfReportPrivate &other) const
	{
		return (m_appType == other.m_appType) &&
		    (m_uniqueId == other.m_uniqueId);
	}

	enum Report::AppType m_appType;
	QString m_uniqueId;
};

Json::ConfReport::ConfReport(void)
    : Object(),
    d_ptr(Q_NULLPTR)
{
}

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

	*d = *other.d_func();
}

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

Json::ConfReport::~ConfReport(void)
{
}

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

Json::ConfReport &Json::ConfReport::operator=(const ConfReport &other) Q_DECL_NOTHROW
{
	if (other.d_func() == Q_NULLPTR) {
		d_ptr.reset(Q_NULLPTR);
		return *this;
	}
	ensureConfReportPrivate(*this);
	Q_D(ConfReport);

	*d = *other.d_func();

	return *this;
}

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

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

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

bool Json::ConfReport::isNull(void) const
{
	Q_D(const ConfReport);
	return d == Q_NULLPTR;
}

bool Json::ConfReport::isValid(void) const
{
	Q_D(const ConfReport);
	return (!isNull()) && (!d->m_uniqueId.isEmpty());
}

enum Json::Report::AppType Json::ConfReport::appType(void) const
{
	Q_D(const ConfReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_APP_TYPE;
	}

	return d->m_appType;
}

void Json::ConfReport::setAppType(enum Report::AppType at)
{
	ensureConfReportPrivate();
	Q_D(ConfReport);
	d->m_appType = at;
}

const QString &Json::ConfReport::uniqueId(void) const
{
	Q_D(const ConfReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullString;
	}

	return d->m_uniqueId;
}

void Json::ConfReport::setUniqueId(const QString &ui)
{
	ensureConfReportPrivate();
	Q_D(ConfReport);
	d->m_uniqueId = ui;
}

#ifdef Q_COMPILER_RVALUE_REFS
void Json::ConfReport::setUniqueId(QString &&ui)
{
	ensureConfReportPrivate();
	Q_D(ConfReport);
	d->m_uniqueId = ::std::move(ui);
}
#endif /* Q_COMPILER_RVALUE_REFS */

bool Json::ConfReport::toJsonVal(QJsonValue &jsonVal) const
{
	QJsonObject jsonObj;

	jsonObj.insert(keyReportVersion, QString(REPORT_VER)); /* value QString */

	if (appType() != Report::AT_UNKNOWN) {
		jsonObj.insert(keyAppType, (int)appType());
	}
	if (!uniqueId().isEmpty()) {
		jsonObj.insert(keyUniqueId, uniqueId());
	}

	jsonObj.insert(keyAppVersion, QString(VERSION)); /* value QString */

	{
#if defined(PORTABLE_APPLICATION)
		int portable = 1;
#else /* !defined(PORTABLE_APPLICATION) */
		int portable = 0;
#endif /* defined(PORTABLE_APPLICATION) */
		jsonObj.insert(keyConfPortableApp, portable);
	}

	{
#if defined(ENABLE_TAGS)
		int tags = 1;
#else /* !defined(ENABLE_TAGS) */
		int tags = 0;
#endif /* defined(ENABLE_TAGS) */
		jsonObj.insert(keyConfTags, tags);
	}

	{
#if defined(QUAZIP_STATIC)
		int bundled_quazip = 1;
#else /* !defined(QUAZIP_STATIC) */
		int bundled_quazip = 0;
#endif /* defined(QUAZIP_STATIC) */
		jsonObj.insert(keyBundedQuazip, bundled_quazip);
	}

	jsonVal = jsonObj;
	return true;
}

class Json::UsageReportPrivate {
public:
	UsageReportPrivate(void)
	    : m_appType(DFLT_APP_TYPE), m_uniqueId(),
	      m_numBoxesProd(DFLT_INT_VAL), m_numBoxesTesting(DFLT_INT_VAL),
	      m_messageDataSizeProd(DFLT_INT_VAL), m_messageDataSizeTesting(DFLT_INT_VAL),
	      m_numDefinedTags(DFLT_INT_VAL),
	      m_usesDatabasesInMemory(DFLT_BOOL_VAL), m_usesPin(DFLT_BOOL_VAL),
	      m_usesRecordsManagement(DFLT_BOOL_VAL)
	{ }

	UsageReportPrivate &operator=(const UsageReportPrivate &other) Q_DECL_NOTHROW
	{
		m_appType = other.m_appType;
		m_uniqueId = other.m_uniqueId;
		m_numBoxesProd = other.m_numBoxesProd;
		m_numBoxesTesting = other.m_numBoxesTesting;
		m_messageDataSizeProd = other.m_messageDataSizeProd;
		m_messageDataSizeTesting = other.m_messageDataSizeTesting;
		m_numDefinedTags = other.m_numDefinedTags;
		m_usesDatabasesInMemory = other.m_usesDatabasesInMemory;
		m_usesPin = other.m_usesPin;
		m_usesRecordsManagement = other.m_usesRecordsManagement;

		return *this;
	}

	bool operator==(const UsageReportPrivate &other) const
	{
		return (m_appType == other.m_appType) &&
		    (m_uniqueId == other.m_uniqueId) &&
		    (m_numBoxesProd == other.m_numBoxesProd) &&
		    (m_numBoxesTesting == other.m_numBoxesTesting) &&
		    (m_messageDataSizeProd == other.m_messageDataSizeProd) &&
		    (m_messageDataSizeTesting == other.m_messageDataSizeTesting) &&
		    (m_numDefinedTags == other.m_numDefinedTags) &&
		    (m_usesDatabasesInMemory == other.m_usesDatabasesInMemory) &&
		    (m_usesPin == other.m_usesPin) &&
		    (m_usesRecordsManagement == other.m_usesRecordsManagement);
	}

	enum Report::AppType m_appType;
	QString m_uniqueId;
	int m_numBoxesProd;
	int m_numBoxesTesting;
	qint64 m_messageDataSizeProd;
	qint64 m_messageDataSizeTesting;
	int m_numDefinedTags;
	bool m_usesDatabasesInMemory;
	bool m_usesPin;
	bool m_usesRecordsManagement;
};

Json::UsageReport::UsageReport(void)
    : Object(),
    d_ptr(Q_NULLPTR)
{
}

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

	*d = *other.d_func();
}

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

Json::UsageReport::~UsageReport(void)
{
}

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

Json::UsageReport &Json::UsageReport::operator=(const UsageReport &other) Q_DECL_NOTHROW
{
	if (other.d_func() == Q_NULLPTR) {
		d_ptr.reset(Q_NULLPTR);
		return *this;
	}
	ensureUsageReportPrivate(*this);
	Q_D(UsageReport);

	*d = *other.d_func();

	return *this;
}

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

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

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

bool Json::UsageReport::isNull(void) const
{
	Q_D(const UsageReport);
	return d == Q_NULLPTR;
}

bool Json::UsageReport::isValid(void) const
{
	Q_D(const UsageReport);
	return (!isNull()) && (!d->m_uniqueId.isEmpty());
}

enum Json::Report::AppType Json::UsageReport::appType(void) const
{
	Q_D(const UsageReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_APP_TYPE;
	}

	return d->m_appType;
}

void Json::UsageReport::setAppType(enum Report::AppType at)
{
	ensureUsageReportPrivate();
	Q_D(UsageReport);
	d->m_appType = at;
}

const QString &Json::UsageReport::uniqueId(void) const
{
	Q_D(const UsageReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return nullString;
	}

	return d->m_uniqueId;
}

void Json::UsageReport::setUniqueId(const QString &ui)
{
	ensureUsageReportPrivate();
	Q_D(UsageReport);
	d->m_uniqueId = ui;
}

#ifdef Q_COMPILER_RVALUE_REFS
void Json::UsageReport::setUniqueId(QString &&ui)
{
	ensureUsageReportPrivate();
	Q_D(UsageReport);
	d->m_uniqueId = ::std::move(ui);
}
#endif /* Q_COMPILER_RVALUE_REFS */

int Json::UsageReport::numBoxesProd(void) const
{
	Q_D(const UsageReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_INT_VAL;
	}

	return d->m_numBoxesProd;
}

void Json::UsageReport::setNumBoxesProd(int nbp)
{
	ensureUsageReportPrivate();
	Q_D(UsageReport);
	d->m_numBoxesProd = nbp;
}

int Json::UsageReport::numBoxesTesting(void) const
{
	Q_D(const UsageReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_INT_VAL;
	}

	return d->m_numBoxesTesting;
}

void Json::UsageReport::setNumBoxesTesting(int nbt)
{
	ensureUsageReportPrivate();
	Q_D(UsageReport);
	d->m_numBoxesTesting = nbt;
}

qint64 Json::UsageReport::messageDataSizeProd(void) const
{
	Q_D(const UsageReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_INT_VAL;
	}

	return d->m_messageDataSizeProd;
}

void Json::UsageReport::setMessageDataSizeProd(qint64 mdsp)
{
	ensureUsageReportPrivate();
	Q_D(UsageReport);
	d->m_messageDataSizeProd = mdsp;
}

qint64 Json::UsageReport::messageDataSizeTesting(void) const
{
	Q_D(const UsageReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_INT_VAL;
	}

	return d->m_messageDataSizeTesting;
}

void Json::UsageReport::setMessageDataSizeTesting(qint64 mdst)
{
	ensureUsageReportPrivate();
	Q_D(UsageReport);
	d->m_messageDataSizeTesting = mdst;
}

int Json::UsageReport::numDefinedTags(void) const
{
	Q_D(const UsageReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_INT_VAL;
	}

	return d->m_numDefinedTags;
}

void Json::UsageReport::setNumDefinedTags(int ndt)
{
	ensureUsageReportPrivate();
	Q_D(UsageReport);
	d->m_numDefinedTags = ndt;
}

bool Json::UsageReport::usesDatabasesInMemory(void) const
{
	Q_D(const UsageReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_BOOL_VAL;
	}

	return d->m_usesDatabasesInMemory;
}

void Json::UsageReport::setUsesDatabasesInMemory(bool udim)
{
	ensureUsageReportPrivate();
	Q_D(UsageReport);
	d->m_usesDatabasesInMemory = udim;
}

bool Json::UsageReport::usesPin(void) const
{
	Q_D(const UsageReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_BOOL_VAL;
	}

	return d->m_usesPin;
}

void Json::UsageReport::setUsesPin(bool up)
{
	ensureUsageReportPrivate();
	Q_D(UsageReport);
	d->m_usesPin = up;
}

bool Json::UsageReport::usesRecordsManagement(void) const
{
	Q_D(const UsageReport);
	if (Q_UNLIKELY(d == Q_NULLPTR)) {
		return DFLT_BOOL_VAL;
	}

	return d->m_usesRecordsManagement;
}

void Json::UsageReport::setUsesRecordsManagement(bool urm)
{
	ensureUsageReportPrivate();
	Q_D(UsageReport);
	d->m_usesRecordsManagement = urm;
}

bool Json::UsageReport::toJsonVal(QJsonValue &jsonVal) const
{
	QJsonObject jsonObj;

	jsonObj.insert(keyReportVersion, QString(REPORT_VER)); /* value QString */

	if (appType() != Report::AT_UNKNOWN) {
		jsonObj.insert(keyAppType, (int)appType());
	}
	if (!uniqueId().isEmpty()) {
		jsonObj.insert(keyUniqueId, uniqueId());
	}

	if (numBoxesProd() >= 0) {
		jsonObj.insert(keyNumBoxesProd, numBoxesProd());
	}
	if (numBoxesTesting() >= 0) {
		jsonObj.insert(keyNumBoxesTesting, numBoxesTesting());
	}
	if (messageDataSizeProd() >= 0) {
		jsonObj.insert(keyMessageDataSizeProd, QString::number(messageDataSizeProd()));
	}
	if (messageDataSizeTesting() >= 0) {
		jsonObj.insert(keyMessageDataSizeTesting, QString::number(messageDataSizeTesting()));
	}
	if (numDefinedTags() >= 0) {
		jsonObj.insert(keyNumDefinedTags, numDefinedTags());
	}
	jsonObj.insert(keyUsesDatabasesInMemory, (int)usesDatabasesInMemory());
	jsonObj.insert(keyUsesPin, (int)usesPin());
	jsonObj.insert(keyUsesRecordsManagement, (int)usesRecordsManagement());

	jsonVal = jsonObj;
	return true;
}
