/*
 * 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.
 */

#pragma once

#include <QDateTime>
#include <QSize>
#include <QString>
#include <QVector>

class AcntId; /* Forward declaration. */
class Prefs; /* Forward declaration. */

/*!
 * @brief Wraps frequently read preferences.
 */
namespace PrefsSpecific {

	enum CertValDate {
		DOWNLOAD_DATE = 1,
		CURRENT_DATE = 2
	};

	enum SelectType {
		SELECT_NEWEST = 1,
		SELECT_LAST_VISITED = 2,
		SELECT_NOTHING = 3
	};

	enum ToolbarButtonStyle {
		ICON_ONLY = 0, /* Qt::ToolButtonIconOnly */
		TEXT_BESIDE_ICON = 2, /* Qt::ToolButtonTextBesideIcon */
		TEXT_UNDER_ICON = 3 /* Qt::ToolButtonTextUnderIcon */
	};

	/*!
	 * @brief Get value "storage.database.messages.on_disk.enabled".
	 */
	bool messageDbOnDisk(const Prefs &prefs);

	/*!
	 * @brief Get value "storage.database.accounts.on_disk.enabled".
	 */
	bool accountDbOnDisk(const Prefs &prefs);

	/*!
	 * @brief Get value "window.main.action.sync_all_accounts.background.enabled".
	 */
	bool backgroundSync(const Prefs &prefs);

	/*!
	 * @brief Get and set value "window.main.action.sync_all_accounts.background.timer.period.minutes".
	 */
	int backgroundSyncTimerMinutes(const Prefs &prefs);
	void setBackgroundSyncTimerMinutes(Prefs &prefs, int val);

	/*!
	 * @brief Get and set value "window.main.action.shadow_sync_all_accounts.background.timer.period.minutes".
	 */
	int shadowSyncTimerMinutes(const Prefs &prefs);
	void setShadowSyncTimerMinutes(Prefs &prefs, int val);

	/*!
	 * @brief Get and set value "application.version.check.enabled".
	 *
	 * @note This functions must be used instead of directly accessing the value.
	 */
	bool checkNewVersionsDefault(void);
	bool canConfigureCheckNewVersions(void);
	bool checkNewVersions(const Prefs &prefs);
	void setCheckNewVersions(Prefs &prefs, bool val);

	/*!
	 * @brief get and set value "application.version.check.timeout.seconds".
	 */
	int checkNewVersionsCooldown(const Prefs &prefs);
	void setCheckNewVersionsCooldown(Prefs &prefs, int val);

	/*!
	 * @brief Get and set value "application.update.automatic_download.enabled".
	 */
	bool canAutoDownloadUpdate(const Prefs &prefs);
	void setCanAutoDownloadUpdate(Prefs &prefs, bool val);

	/*!
	 * @brief Get and set "application.update.automatic_download.attempt.max".
	 */
	int autoDownloadUpdateAttemptMax(const Prefs &prefs);
	void setAutoDownloadUpdateAttemptMax(Prefs &prefs, int val);

	/*!
	 * @brief Get and set value "application.update.downloaded_package.version".
	 */
	QString downloadedPkgVersion(const Prefs &prefs);
	void setDownloadedPkgVersion(Prefs &prefs, const QString &val);

	/*!
	 * @brief Get and set value "application.update.downloaded_package.sha256sum"
	 */
	QString downloadedPkgSha256Sum(const Prefs &prefs);
	void setDownloadedPkgSha256Sum(Prefs &prefs, const QString &val);

	/*!
	 * @brief Get and set value "application.update.downloaded_package.path".
	 */
	QString downloadedPkgPath(const Prefs &prefs);
	void setDownloadedPkgPath(Prefs &prefs, const QString &val);

	/*!
	 * @brief Get value "network.isds.communication.timeout.ms".
	 */
	int isdsDownloadTimeoutMs(const Prefs &prefs);

	/*!
	 * @brief Get value "crypto.message.validation.date.type".
	 */
	enum CertValDate certValDate(const Prefs &prefs);

	/*!
	 * @brief Get value "crypto.crl.check.enabled".
	 *
	 * @return True if enabled.
	 */
	bool checkCrl(const Prefs &prefs);

	/*!
	 * @brief Get and set the value "global.path.enabled".
	 */
	bool useGlobalPaths(const Prefs &prefs);
	void setUseGlobalPaths(Prefs &prefs, bool val);

	/*!
	 * @brief Get and set value "records_management.action.automatic_upload.enabled".
	 */
	bool recMgmtAutoUpload(const Prefs &prefs);
	void setRecMgmtAutoUpload(Prefs &prefs, bool val);

	/*!
	 * @brief Get value "records_management.action.automatic_account_status_upload.enabled".
	 */
	bool recMgmtAutoAcntStatusUpload(const Prefs &prefs);

	/*!
	 * @brief Get and set the value "global.path.save.attachment".
	 */
	QString saveAttachDir(const Prefs &prefs);
	void setSaveAttachDir(Prefs &prefs, const QString &val);

	/*!
	 * @brief Get and set the value "global.path.load.attachment".
	 */
	QString loadAttachDir(const Prefs &prefs);
	void setLoadAttachDir(Prefs &prefs, const QString &val);

	/*!
	 * @brief Get and set the value "global.path.load.zfo".
	 */
	QString viewZfoDir(const Prefs &prefs);
	void setViewZfoDir(Prefs &prefs, const QString &val);

	/*!
	 * @brief Get and set the value "global.path.import.database".
	 */
	QString importDbDir(const Prefs &prefs);
	void setImportDbDir(Prefs &prefs, const QString &val);

	/*!
	 * @brief Get and set the value "global.path.import.zfo".
	 */
	QString importDbZfo(const Prefs &prefs);
	void setImportDbZfo(Prefs &prefs, const QString &val);

	/*!
	 * @brief Get and set the value "account.*.last.path.save.attachment".
	 */
	QString acntSaveAttachDir(const Prefs &prefs, const AcntId &acntId);
	void setAcntSaveAttachDir(Prefs &prefs, const AcntId &acntId, const QString &val);

	/*!
	 * @brief Get and set the value "account.*.last.path.load.attachment".
	 */
	QString anctLoadAttachDir(const Prefs &prefs, const AcntId &acntId);
	void setAnctLoadAttachDir(Prefs &prefs, const AcntId &acntId, const QString &val);

	/*!
	 * @brief Get and set the value "account.*.last.path.save.correspondence_overview".
	 */
	QString acntCorrespondenceDir(const Prefs &prefs, const AcntId &acntId);
	void setAcntCorrespondenceDir(Prefs &prefs, const AcntId &acntId, const QString &val);

	/*!
	 * @brief Get and set the value "account.*.last.path.save.zfo".
	 */
	QString acntZfoDir(const Prefs &prefs, const AcntId &acntId);
	void setAcntZfoDir(Prefs &prefs, const AcntId &acntId, const QString &val);

	/*!
	 * @brief Get and set the value "window.create_message.notification.send_pdz.enabled".
	 */
	bool showPdzNotification(const Prefs &prefs);
	void setShowPdzNotification(Prefs &prefs, bool val);

	/*!
	 * @brief Get and set the value "window.about.notification.update.quit_app.enabled".
	 */
	bool showUpdateQuitAppNotification(const Prefs &prefs);
	void setShowUpdateQuitAppNotification(Prefs &prefs, bool val);

	/*!
	 * @brief Get value "action.send_message.tie.action.download_message.timeout.ms".
	 */
	int sentMsgDownloadWaitIntervalMs(const Prefs &prefs);

	qint64 bytesInMByte(const Prefs &prefs);
	int maxAttachmentMBytes(const Prefs &prefs);
	int maxOVMAttachmentMBytes(const Prefs &prefs);
	int maxVoDZAttachmentMBytes(const Prefs &prefs);
	int maxAttachmentNum(const Prefs &prefs);

	/*!
	 * @brief Get value "window.send_message.vodz.enable".
	 */
	bool enableVodzSending(const Prefs &prefs);

	/*!
	 * @brief Get/set dialogue size for dialogue with given name.
	 */
	QSize dlgSize(const Prefs &prefs, const QString &name);
	void setDlgSize(Prefs &prefs, const QString &name, const QSize &val,
	    const QSize &dfltVal);

	/*!
	 * @brief Get/set relative table column widths for dialogue with given
	 *     name and table name.
	 */
	QVector<double> dlgTblRelColWidths(const Prefs &prefs, const QString &dlgName,
	    const QString &tblName);
	void setDlgTblRelColWidths(Prefs &prefs, const QString &dlgName,
	    const QString &tblName, const QVector<double> &val);

	/*!
	 * @brief Get/set table column widths for main window with table name.
	 */
	QVector<qint64> mainWinColWidths(const Prefs &prefs,
	    const QString &tblName);
	void setMainWinTblColWidths(Prefs &prefs, const QString &tblName,
	    const QVector<qint64> &val);

	/*!
	 * @brief Get/set splitter size for dialogue with given
	 *     name and splitter name.
	 */
	int dlgSplitterSize(const Prefs &prefs, const QString &dlgName,
	    const QString &splitterName);
	void setDlgSplitterSize(Prefs &prefs, const QString &dlgName,
	    const QString &splitterName, int val);

	/*!
	 * @brief Get/set table column sort order for dialogue with given
	 *     name and table name.
	 */
	QVector<int> dlgTblColSortOrder(const Prefs &prefs, const QString &dlgName,
	    const QString &tblName);
	void setDlgTblColSortOrder(Prefs &prefs, const QString &dlgName,
	    const QString &tblName, const QVector<int> &val);

	/*!
	 * @brief Get/set column sort order for main window with table name.
	 */
	QVector<int> mainWinTblColSortOrder(const Prefs &prefs,
	    const QString &tblName);
	void setMainWinTblColSortOrder(Prefs &prefs, const QString &tblName,
	    const QVector<int> &val);

	/*!
	 * @brief Get value "file_system.format.filename.export.truncate.max_chars".
	 */
	int exportedNamesParamMaxLength(const Prefs &prefs);

	/*!
	 * @brief Get/store first application start-up time.
	 *
	 * @return First application launch time.
	 */
	QDateTime appFirstLaunchTime(const Prefs &prefs);
	void storeAppFirstLaunchTime(Prefs &prefs);

	/*!
	 * @brief Get/store last application launch time.
	 *
	 * @return Last application launch time.
	 */
	QDateTime appLastLaunchTime(const Prefs &prefs);
	void storeAppLastLaunchTime(Prefs &prefs);

	/*!
	 * @brief Get/set next donation dialogue view time.
	 *
	 * @param[in] nextViewTime Next view datetime.
	 *
	 * @return Next view datetime.
	 */
	QDateTime appPlannedDonationViewTime(const Prefs &prefs);
	void setAppPlannedDonationViewTime(Prefs &prefs,
	    const QDateTime &nextViewTime);

	/*!
	 * @brief Compute next view donation dialogue datetime.
	 *
	 * @param[in] shortTime True if planned short view interval.
	*/
	void planNextDonationViewTime(Prefs &prefs, bool shortTime);

	/*!
	 * @brief Check whether to show the donation dialogue.
	 *
	 * @return True if show donation dialogue.
	*/
	bool isTimeToShowDonationDlg(Prefs &prefs);

	/*!
	 * @brief Get/set number of application launches.
	 *
	 * @return Number of application launches.
	 */
	qint64 appLaunchCount(const Prefs &prefs);
	void incrementLaunchCount(Prefs &prefs);

	/*!
	 * @brief Get and set value "stats.app.report.unique_id".
	 */
	QString statsReportUniqueId(const Prefs &prefs);
	void setStatsReportUniqueId(Prefs &prefs, const QString &val);

	/*!
	 * @brief Get and set value "stats.app.report.action.ask_consent.datetime".
	 */
	QDateTime statsReportLastConsentRequest(const Prefs &prefs);
	void setStatsReportLastConsentRequest(Prefs &prefs,
	    const QDateTime &lastConsentDateTime);

	/*!
	 * @brief Get and set value "stats.app.report.usage.send.enabled".
	 */
	bool statsReportUsage(const Prefs &prefs);
	void setStatsReportUsage(Prefs &prefs, bool enabled);
}
