#ifndef CONNECTIONCONTROLLER_H
#define CONNECTIONCONTROLLER_H

#include <QObject>
#include <string_view>

class MasterController;
class ConnectionConfig;
class ConnectionConfigurationWidget;
class ConnectionList;
class ConnectionTreeModel;
class ConnectionManagerWindow;
class PasswordManager;
class QTimer;
class QSqlDatabase;


class PassphraseResult {
public:
    bool success;
    QString passphrase;
    int rememberForMinutes;
};


class ConnectionController : public QObject {
	Q_OBJECT
public:
	explicit ConnectionController(MasterController *parent = nullptr);
	~ConnectionController();

	void init();

	ConnectionTreeModel *getConnectionTreeModel()
	{
		return m_connectionTreeModel;
	}

	void showConnectionManager();
	void openSqlWindowForConnection(QModelIndex index);
    void openSqlWindowForConnection(const ConnectionConfig &cfg);
    void openBackupDlgForConnection(QModelIndex index);

	/// Starts the form for creating a new conncetion.
	/// This function returns immidiatly!
	void createConnection();
	/// Starts the form for editing a conncetion.
	/// This function returns immidiatly!
	void editConnection(QModelIndex index);
    void editCopy(QModelIndex index);
    void addGroup();
	void removeGroup(QModelIndex index);

	std::shared_ptr<PasswordManager> passwordManager();
    /** Retrieves the connection password from the user (directly or through the psk db)
     *
     */
    bool retrieveConnectionPassword(ConnectionConfig &cc);

    bool UnlockPasswordManagerIfNeeded();

    bool decodeConnectionPassword(QUuid id, QByteArray encoded, QString &out_password);
    void resetPasswordManager();
private:
	MasterController *m_masterController;
	ConnectionList *m_connectionList = nullptr;
	ConnectionTreeModel *m_connectionTreeModel = nullptr;
	ConnectionManagerWindow *m_connectionManagerWindow = nullptr;
	QTimer *m_relockTimer = nullptr;

	/** Using long lived object so it can remember its master password for sometime
	 * if the user wishes it.
	 */
	std::shared_ptr<PasswordManager> m_passwordManager;

    bool retrieveFromPasswordManager(const std::string &password_id, const std::string_view &enc_password, std::string &password);

    /// Expects the plaintext password to be the password that needs encoding.
    bool encryptPassword(ConnectionConfig &cc);

    static std::string getPskId(QUuid connectionid);

    void editConfig(ConnectionConfig &cc);
    void saveConnection(ConnectionConfigurationWidget &w);
    void setRelockTimer(int rem_minutes);
    PassphraseResult PassphrasePrompt();
    /// Asks user for new passphares and initialize the password manager.
    bool InitializePasswordManager();
private slots:
	void relock();
};


#endif // CONNECTIONCONTROLLER_H
