#ifndef PASSWORDMANAGER_H
#define PASSWORDMANAGER_H

#include "utils/KeyStrengthener.h"
#include <botan/secmem.h>
#include <string>
#include <string_view>
#include <tuple>
#include <memory>

#include <botan/pwdhash.h>

namespace Botan {

    class Encrypted_PSK_Database;
    class PasswordHash;

}

class PasswordManagerException: public std::exception {
public:
    using std::exception::exception; //(char const* const _Message);
};

class PasswordManagerLockedException: public PasswordManagerException {
public:
    using PasswordManagerException::PasswordManagerException;

};
class PasswordCryptoEngine;

class PasswordManager {
public:
    enum Result {
        Ok,
        Locked,
        Error
    };

    PasswordManager();
    ~PasswordManager();

    /** Check if it has been initialized before.
     *
     * If returns false then use createDatabase to set it up
     * else use openDatabase to get access.
     */
    bool initialized(SQLiteConnection &db);
    bool createDatabase(SQLiteConnection &db, QString passphrase);
    /// Opens the PSK database
    bool openDatabase(SQLiteConnection &db, QString passphrase);
    void closeDatabase();
    bool locked() const;
    void resetMasterPassword(SQLiteConnection &db);


    std::string encrypt(const std::string &id, const std::string &passwd);
    std::string decrypt(const std::string &id, const std::string_view &encpwd);

private:
    QString m_passwordTableName   = "psk_passwd";
    QString m_secretAlgoTableName = "psk_masterkey_algo";
    QString m_secretHashTableName = "psk_masterkey_hash";
    std::unique_ptr<PasswordCryptoEngine> m_cryptoEngine;

    bool isPskStoreInitialized(SQLiteConnection& db);
    void initializeNewPskStore(SQLiteConnection &db);

    /// Get PasswordHash from parameters in database
    KeyStrengthener getKeyStrengthener(SQLiteConnection &db);
    KeyStrengthener createKeyStrengthener();

    std::tuple<Botan::secure_vector<uint8_t>, Botan::secure_vector<uint8_t>>
    deriveKey(KeyStrengthener &ks, QString passphrase);
};


#endif // PASSWORDMANAGER_H
