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

#pragma once

#include <QDate>
#include <QDateTime>
#include <QList>
#include <QString>
#include <QStringList>
#include <QVariant>

#include "src/datovka_shared/io/sqlite/db_single.h"

/*!
 * @brief Encapsulates preferences database.
 */
class PrefsDb : public SQLiteDbSingle {

public:
	/*!
	 * @brief Types of values held in the preferences database.
	 *
	 * @note Do not change the values of the enumerations as they are
	 *     stored in the tables by their integer values.
	 */
	enum ValueType {
		/* Value 0 is intentionally not used. */
		VAL_BOOLEAN = 1, /* Stored as 'false' or 'true'. */
		VAL_INTEGER = 2, /* Stored as a string. */
		VAL_FLOAT = 4, /* Stored as a string. */
		VAL_STRING = 8,
		VAL_COLOUR = 10, /* Stored as string containing a colour value in 6-digit the format 'RRGGBB'. */
		VAL_DATETIME = 16, /* Stored as a string containing UTC value in ISO 861 format with milliseconds. */
		VAL_DATE = 17 /* Stored as a string in ISO 8601 format 'YYYY-MM_DD'. */
	};

	/* Use parent class constructor. */
	using SQLiteDbSingle::SQLiteDbSingle;

	/*!
	 * @brief Check whether database contains an entry.
	 *
	 * @param[in] name Entry name.
	 * @return True if entry with given name found, false if not found or
	 *     on any error.
	 */
	bool contains(const QString &name) const;

	/*!
	 * @brief Remove entry.
	 *
	 * @param[in] name Entry name.
	 * @return true on success, false on failure.
	 */
	bool erase(const QString &name);

	/*!
	 * @brief Get names of all entries.
	 *
	 * @return List of all held entry name.
	 */
	QStringList names(void) const;

	/*!
	 * @brief Get type and value of the entry with supplied name.
	 *
	 * @param[in]  name Entry name.
	 * @param[out] type Type of entry.
	 * @param[out] val Entry value.
	 * @return True on success, false on any error.
	 */
	bool type(const QString &name, enum ValueType &type,
	    QVariant *val = Q_NULLPTR) const;

	bool setBoolVal(const QString &name, bool val);
	bool boolVal(const QString &name, bool &val) const;

	bool setIntVal(const QString &name, qint64 val);
	bool intVal(const QString &name, qint64 &val) const;

	bool setFloatVal(const QString &name, double val);
	bool floatVal(const QString &name, double &val) const;

	bool setStrVal(const QString &name, const QString &val);
	bool strVal(const QString &name, QString &val) const;

	bool setColourVal(const QString &name, const QString &val);
	bool colourVal(const QString &name, QString &val) const;

	bool setDateTimeVal(const QString &name, const QDateTime &val);
	bool dateTimeVal(const QString &name, QDateTime &val) const;

	bool setDateVal(const QString &name, const QDate &val);
	bool dateVal(const QString &name, QDate &val) const;

	/*!
	 * @brief Converts date and time to string in ISO format.
	 */
	static
	QString dateTimeToString(const QDateTime &val);

	/*!
	 * @brief Converts string in ISO format to date and time.
	 */
	static
	QDateTime stringToDateTime(const QString &str);

protected:
	/*!
	 * @brief Returns list of tables.
	 *
	 * @return List of pointers to tables.
	 */
	virtual
	QList<class SQLiteTbl *> listOfTables(void) const Q_DECL_OVERRIDE;
};
