/*
 * Copyright (C) 2016 Canonical Ltd.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2 or version 3 of the License.
 * See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
 */

#ifndef SNAPD_REQUEST_H
#define SNAPD_REQUEST_H

#include <QtCore/QObject>
#include <QtCore/QScopedPointer>
#include <Snapd/Change>

class QSnapdRequestPrivate;

#include "snapdqt_global.h"

class LIBSNAPDQT_EXPORT QSnapdRequest : public QObject {
  Q_OBJECT

  Q_PROPERTY(bool isFinished READ isFinished)
  Q_PROPERTY(QSnapdError error READ error)
  Q_PROPERTY(QString errorString READ errorString)
  Q_PROPERTY(QSnapdChange change READ change)

public:
  enum QSnapdError {
    NoError,
    UnknownError,
    ConnectionFailed,
    WriteFailed,
    ReadFailed,
    BadRequest,
    BadResponse,
    AuthDataRequired,
    AuthDataInvalid,
    TwoFactorRequired,
    TwoFactorInvalid,
    PermissionDenied,
    Failed,
    TermsNotAccepted,
    PaymentNotSetup,
    PaymentDeclined,
    AlreadyInstalled,
    NotInstalled,
    NoUpdateAvailable,
    PasswordPolicyError,
    NeedsDevmode,
    NeedsClassic,
    NeedsClassicSystem,
    Cancelled,
    BadQuery,
    NetworkTimeout,
    NotFound,
    NotInStore,
    AuthCancelled,
    NotClassic,
    RevisionNotAvailable,
    ChannelNotAvailable,
    NotASnap,
    DNSFailure,
    OptionNotFound,
    AppNotFound,
    ArchitectureNotAvailable,
    ChangeConflict,
    InterfacesUnchanged
  };
  Q_ENUM(QSnapdError)

  explicit QSnapdRequest(void *snapd_client, QObject *parent = 0);
  ~QSnapdRequest();
  bool isFinished() const;
  QSnapdError error() const;
  QString errorString() const;
  Q_INVOKABLE virtual void runSync() = 0;
  Q_INVOKABLE virtual void runAsync() = 0;
  Q_INVOKABLE void cancel();
  Q_INVOKABLE QSnapdChange *change() const;
  void handleProgress(void *);

protected:
  void *getClient() const;
  void *getCancellable() const;
  void finish(void *error);

Q_SIGNALS:
  void progress();
  void complete();

private:
  QScopedPointer<QSnapdRequestPrivate> d_ptr;
  Q_DECLARE_PRIVATE(QSnapdRequest);
};

#endif
