/*
 * Copyright (C) 2014-2019 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 <Qt> /* enum Qt::ToolButtonStyle */

#include "src/datovka_shared/log/log.h"
#include "src/datovka_shared/settings/prefs.h"
#include "src/settings/prefs_specific.h"
#include "src/settings/registry.h"

bool PrefsSpecific::messageDbOnDisk(const Prefs &prefs)
{
	bool val = false;
	return prefs.boolVal("storage.database.messages.on_disk.enabled",
	    val) && val;
}

bool PrefsSpecific::accountDbOnDisk(const Prefs &prefs)
{
	bool val = false;
	return prefs.boolVal("storage.database.accounts.on_disk.enabled",
	    val) && val;
}

bool PrefsSpecific::backgroundSync(const Prefs &prefs)
{
	bool val = false;
	return prefs.boolVal(
	    "window.main.action.sync_all_accounts.background.enabled", val) && val;
}

int PrefsSpecific::backgroundSyncTimerMinutes(const Prefs &prefs)
{
	qint64 val = 10;
	if (Q_UNLIKELY(!prefs.intVal(
	        "window.main.action.sync_all_accounts.background.timer.period.minutes",
	        val))) {
		Q_ASSERT(0);
		return 10;
	}
	return val;
}

void PrefsSpecific::setBackgroundSyncTimerMinutes(Prefs &prefs, int val)
{
	if (val < 5) {
		val = 5;
	}
	prefs.setIntVal(
	    "window.main.action.sync_all_accounts.background.timer.period.minutes",
	    val);
}

bool PrefsSpecific::checkNewVersionsDefault(void)
{
#ifdef DISABLE_VERSION_CHECK_BY_DEFAULT
	return false;
#else /* !DISABLE_VERSION_CHECK_BY_DEFAULT */
	return true;
#endif /* DISABLE_VERSION_CHECK_BY_DEFAULT */
}

bool PrefsSpecific::canConfigureCheckNewVersions(void)
{
#if defined(DISABLE_VERSION_NOTIFICATION)
	return false;
#elif defined(Q_OS_WIN) /* !DISABLE_VERSION_NOTIFICATION */
	/* Registry settings can override the default behaviour. */
	return !(
	    RegPreferences::haveEntry(RegPreferences::LOC_POL,
	        RegPreferences::ENTR_DISABLE_VER_NOTIF) ||
	    RegPreferences::haveEntry(RegPreferences::LOC_SYS,
	        RegPreferences::ENTR_DISABLE_VER_NOTIF) ||
	    RegPreferences::haveEntry(RegPreferences::LOC_USR,
	        RegPreferences::ENTR_DISABLE_VER_NOTIF));
#else /* !Q_OS_WIN */
	return true;
#endif /* Q_OS_WIN */
}

bool PrefsSpecific::checkNewVersions(const Prefs &prefs)
{
	if (canConfigureCheckNewVersions()) {
		bool val = false;
		return prefs.boolVal(
		    "application.version.check.enabled", val) && val;
	} else {
#if defined(DISABLE_VERSION_NOTIFICATION)
		logInfoNL("%s",
		    "Version notification disabled at compile time.");
		return false;
#elif defined(Q_OS_WIN) /* !DISABLE_VERSION_NOTIFICATION */
		if (RegPreferences::haveEntry(RegPreferences::LOC_POL,
		        RegPreferences::ENTR_DISABLE_VER_NOTIF)) {
			return !RegPreferences::disableVersionNotification(
			    RegPreferences::LOC_POL);
		} else if (RegPreferences::haveEntry(RegPreferences::LOC_SYS,
		        RegPreferences::ENTR_DISABLE_VER_NOTIF)) {
			return !RegPreferences::disableVersionNotification(
			    RegPreferences::LOC_SYS);
		} else if (RegPreferences::haveEntry(RegPreferences::LOC_USR,
		        RegPreferences::ENTR_DISABLE_VER_NOTIF)) {
			return !RegPreferences::disableVersionNotification(
			    RegPreferences::LOC_USR);
		} else {
			/*
			 * The value could be deleted manually in between
			 * the calls.
			 */
			return checkNewVersionsDefault();
		}
#else /* !Q_OS_WIN */
		return checkNewVersionsDefault();
#endif /* Q_OS_WIN */
	}
}

void PrefsSpecific::setCheckNewVersions(Prefs &prefs, bool val)
{
	prefs.setBoolVal("application.version.check.enabled", val);
}

bool PrefsSpecific::sendStatsWithVersionChecks(const Prefs &prefs)
{
	bool val = false;
	return prefs.boolVal(
	    "application.version.check.stats.send.enabled", val) && val;
}

void PrefsSpecific::setSendStatsWithVersionChecks(Prefs &prefs, bool val)
{
	prefs.setBoolVal("application.version.check.stats.send.enabled", val);
}

int PrefsSpecific::isdsDownloadTimeoutMs(const Prefs &prefs)
{
	qint64 val = 0;
	if (Q_UNLIKELY(!prefs.intVal("network.isds.communication.timeout.ms",
	        val))) {
		Q_ASSERT(0);
		return 600000;
	}
	return val;
}

enum PrefsSpecific::CertValDate PrefsSpecific::certValDate(const Prefs &prefs)
{
	qint64 val = DOWNLOAD_DATE;
	if (Q_UNLIKELY(!prefs.intVal("crypto.message.validation.date.type",
	        val))) {
		Q_ASSERT(0);
		return DOWNLOAD_DATE;
	}
	switch (val) {
	case DOWNLOAD_DATE:
		return DOWNLOAD_DATE;
		break;
	case CURRENT_DATE:
		return CURRENT_DATE;
		break;
	default:
		Q_ASSERT(0);
		return DOWNLOAD_DATE;
		break;
	}
}

bool PrefsSpecific::checkCrl(const Prefs &prefs)
{
	bool val = false;
	return prefs.boolVal("crypto.crl.check.enabled", val) && val;
}

bool PrefsSpecific::useGlobalPaths(const Prefs &prefs)
{
	bool val = false;
	return prefs.boolVal("global.path.enabled", val) && val;
}

int PrefsSpecific::qtToolButtonStyle(int style)
{
	switch (style) {
	case ICON_ONLY:
		return Qt::ToolButtonIconOnly;
		break;
	case TEXT_BESIDE_ICON:
		return Qt::ToolButtonTextBesideIcon;
		break;
	case TEXT_UNDER_ICON:
		return Qt::ToolButtonTextUnderIcon;
		break;
	default:
		Q_ASSERT(0);
		return Qt::ToolButtonTextUnderIcon; /* Default. */
		break;
	}
}

bool PrefsSpecific::recMgmtAutoUpload(const Prefs &prefs)
{
	bool val = false;
	return prefs.boolVal("records_management.action.automatic_upload.enabled", val) && val;
}

void PrefsSpecific::setRecMgmtAutoUpload(Prefs &prefs, bool val)
{
	prefs.setBoolVal("records_management.action.automatic_upload.enabled", val);
}
