/*
 * Copyright (C) 2014-2026 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 <QObject>
#include <QTimer>

class AccountsMap; /* Forward declaration. */
class IsdsSessions; /* Forward declaration. */
class QThread; /* Forward declaration. */

/*!
 * @brief Holds session keeper thread and launches it periodically.
 */
class SessionKeeper : public QObject {
	Q_OBJECT
public:
	/* Values don't match AcntSettings::LoginMethod. */
	enum LoginType {
		LT_UNAME_PWD = 0x01, /*!< Username and password. */
		LT_UNAME_CRT = 0x02, /*!< Username and certificate. */
		LT_UNAME_PWD_CRT = 0x04, /*!< Username, password and certificate. */
		LT_UNAME_PWD_HOTP = 0x08, /*!< Username, password and HOTP. */
		LT_UNAME_PWD_TOTP = 0x10, /*!< Username, password and TOTP (SMS). */
		LT_UNAME_MEP = 0x20 /*!< Username and MEP (mobile key app). */
	};

	/*!
	 * @brief Constructor.
	 *
	 * @param[in] regularAccounts Account container holding regular accounts.
	 * @param[in] sessions Session container.
	 * @param[in] parent Parent object.
	 */
	explicit SessionKeeper(AccountsMap *regularAccounts,
	    IsdsSessions *sessions, QObject *parent = Q_NULLPTR);

	/*!
	 * @brief Destructor. Stops the running thread and waits for
	 *     the thread to finish.
	 */
	~SessionKeeper(void);

	/*!
	 * @brief Sets whether to quit session that fail to ping.
	 *
	 * @paran[in] quitInactive Quit inactive sessions.
	 */
	void setQuitInactive(bool quitInactive);

	/*!
	 * @brief Return whether to quit sessions that fail to ping.
	 *
	 * @return Whether to quit inactive sessions.
	 */
	bool quitInactive(void) const;

	/*!
	 * @brief Determines which account should be kept alive according to
	 *     their login methods.
	 *
	 * @param[in] processedTypeFlags Flags composed from enum LoginType.
	 */
	void setProcessedTypeFlags(int processedTypeFlags);

	/*!
	 * @brief Return flags determining which account should be kept alive.
	 *
	 * @return Flags composed from enum LoginType.
	 */
	int processedTypeFlags(void) const;

	/*!
	 * @brief Set cool-down time. Keep-alive thread is not started if the
	 *     time since last time the thread was executed was shorter than
	 *     the cool-down time. Cool down is ignored if set to 0.
	 *
	 * @note default value is 0.
	 *
	 * @param[in] msec Cool-down in milliseconds. Negative values are treated as 0.
	 */
	void setCoolDown(int msec);

	/*!
	 * @brief Starts the keep-alive timer which will periodically start
	 *     the keep-alive thread.
	 *
	 * @note It executes QTimer::start(int).
	 *
	 * @param[in] msec Period os the keep-alive timer.
	 */
	void startKeepAlive(int msec);

	/*!
	 * @brief Stop the keep-alive thread.
	 */
	void stopKeepAlive(void);

private Q_SLOTS:
	/*!
	 * @brief Checks the cool-down period and starts the keep-alive thread.
	 */
	void runKeepAlive(void);

private:
	QThread *m_keepAliveThread; /*!< Keep-alive thread. */
	QTimer m_keepAliveTimer; /*!< Starts the keep-alive thread. */

	bool m_quitInactive; /*!< Whether to quit inactive sessions. */
	int m_processedTypeFlags; /*!< Account types that should be kept alive. */
	int m_coolDown; /*!< Cool-down period in milliseconds. */
};
