#ifndef GROUPSESSION_H
#define GROUPSESSION_H

#include "olm/olm.h"

#include <QByteArray>
#include <QObject>

namespace QtOlm {
class InboundGroupSession : public QObject {
  Q_OBJECT
  Q_PROPERTY(QString id READ id)
  Q_PROPERTY(int firstKnownIndex READ firstKnownIndex)
 public:
  enum Initialization {
    Init,
    Import,
  };

  explicit InboundGroupSession(QByteArray sessionKey,
                               Initialization type = Initialization::Init,
                               QObject* parent = nullptr);
  InboundGroupSession(QByteArray sessionKey,
                      QByteArray pickle,
                      QString passphrase = "",
                      QObject* parent = nullptr);
  ~InboundGroupSession();

  QByteArray pickle(QString passphrase = "");

  std::pair<QString, uint32_t> decrypt(QByteArray cipherText);

  QString id();
  int firstKnownIndex();

  QByteArray exportSession(int messageIndex);

 private:
  static OlmInboundGroupSession* newSession();

 protected:
  void checkErr(size_t code);

  OlmInboundGroupSession* _session;
};

class OutboundGroupSession : public QObject {
  Q_OBJECT
  Q_PROPERTY(QString id READ id)
  Q_PROPERTY(int messageIndex READ messageIndex)
  Q_PROPERTY(QByteArray sessionKey READ sessionKey)
 public:
  explicit OutboundGroupSession(QObject* parent = nullptr);
  OutboundGroupSession(QByteArray pickle,
                       QString passphrase = "",
                       QObject* parent = nullptr);
  ~OutboundGroupSession();

  QByteArray pickle(QString passphrase = "");

  QByteArray encrypt(QString plainText);

  QString id();
  int messageIndex();
  QByteArray sessionKey();

 private:
  static OlmOutboundGroupSession* newSession();

 protected:
  void checkErr(size_t code);

  OlmOutboundGroupSession* _session;
};
}  // namespace QtOlm

#endif  // GROUPSESSION_H
