/******************************************************************************
 * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
 */

#pragma once

#include "converters.h"

#include "csapi/../identity/definitions/sid.h"
#include "csapi/definitions/auth_data.h"

#include "jobs/basejob.h"

namespace Quotient
{

// Operations

/// Register for an account on this homeserver.
/*!
 * This API endpoint uses the `User-Interactive Authentication API`_.
 *
 * Register for an account on this homeserver.
 *
 * There are two kinds of user account:
 *
 * - `user` accounts. These accounts may use the full API described in this
 * specification.
 *
 * - `guest` accounts. These accounts may have limited permissions and may not
 * be supported by all servers.
 *
 * If registration is successful, this endpoint will issue an access token
 * the client can use to authorize itself in subsequent requests.
 *
 * If the client does not supply a ``device_id``, the server must
 * auto-generate one.
 *
 * The server SHOULD register an account with a User ID based on the
 * ``username`` provided, if any. Note that the grammar of Matrix User ID
 * localparts is restricted, so the server MUST either map the provided
 * ``username`` onto a ``user_id`` in a logical manner, or reject
 * ``username``\s which do not comply to the grammar, with
 * ``M_INVALID_USERNAME``.
 *
 * Matrix clients MUST NOT assume that localpart of the registered
 * ``user_id`` matches the provided ``username``.
 *
 * The returned access token must be associated with the ``device_id``
 * supplied by the client or generated by the server. The server may
 * invalidate any access token previously associated with that device. See
 * `Relationship between access tokens and devices`_.
 */
class RegisterJob : public BaseJob
{
public:
    /*! Register for an account on this homeserver.
     * \param kind
     *   The kind of account to register. Defaults to `user`.
     * \param auth
     *   Additional authentication information for the
     *   user-interactive authentication API. Note that this
     *   information is *not* used to define how the registered user
     *   should be authenticated, but is instead used to
     *   authenticate the ``register`` call itself. It should be
     *   left empty, or omitted, unless an earlier call returned an
     *   response with status code 401.
     * \param bindEmail
     *   If true, the server binds the email used for authentication to
     *   the Matrix ID with the identity server.
     * \param username
     *   The basis for the localpart of the desired Matrix ID. If omitted,
     *   the homeserver MUST generate a Matrix ID local part.
     * \param password
     *   The desired password for the account.
     * \param deviceId
     *   ID of the client device. If this does not correspond to a
     *   known client device, a new device will be created. The server
     *   will auto-generate a device_id if this is not specified.
     * \param initialDeviceDisplayName
     *   A display name to assign to the newly-created device. Ignored
     *   if ``device_id`` corresponds to a known device.
     * \param inhibitLogin
     *   If true, an ``access_token`` and ``device_id`` should not be
     *   returned from this call, therefore preventing an automatic
     *   login. Defaults to false.
     */
    explicit RegisterJob(const QString& kind = QStringLiteral("user"),
                         const Omittable<AuthenticationData>& auth = none,
                         Omittable<bool> bindEmail = none,
                         const QString& username = {},
                         const QString& password = {},
                         const QString& deviceId = {},
                         const QString& initialDeviceDisplayName = {},
                         Omittable<bool> inhibitLogin = none);

    ~RegisterJob() override;

    // Result properties

    /// The fully-qualified Matrix user ID (MXID) that has been registered.
    ///
    /// Any user ID returned by this API must conform to the grammar given in
    /// the `Matrix specification
    /// <https://matrix.org/docs/spec/appendices.html#user-identifiers>`_.
    const QString& userId() const;
    /// An access token for the account.
    /// This access token can then be used to authorize other requests.
    /// Required if the ``inhibit_login`` option is false.
    const QString& accessToken() const;
    /// The server_name of the homeserver on which the account has
    /// been registered.
    ///
    /// **Deprecated**. Clients should extract the server_name from
    /// ``user_id`` (by splitting at the first colon) if they require
    /// it. Note also that ``homeserver`` is not spelt this way.
    const QString& homeServer() const;
    /// ID of the registered device. Will be the same as the
    /// corresponding parameter in the request, if one was specified.
    /// Required if the ``inhibit_login`` option is false.
    const QString& deviceId() const;

protected:
    Status parseJson(const QJsonDocument& data) override;

private:
    class Private;
    QScopedPointer<Private> d;
};

/// Begins the validation process for an email to be used during registration.
/*!
 * Proxies the Identity Service API ``validate/email/requestToken``, but
 * first checks that the given email address is not already associated
 * with an account on this homeserver. See the Identity Service API for
 * further information.
 */
class RequestTokenToRegisterEmailJob : public BaseJob
{
public:
    /*! Begins the validation process for an email to be used during
     * registration. \param clientSecret A unique string generated by the
     * client, and used to identify the validation attempt. It must be a string
     * consisting of the characters
     *   ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it
     *   must not be empty.
     * \param email
     *   The email address to validate.
     * \param sendAttempt
     *   The server will only send an email if the ``send_attempt``
     *   is a number greater than the most recent one which it has seen,
     *   scoped to that ``email`` + ``client_secret`` pair. This is to
     *   avoid repeatedly sending the same email in the case of request
     *   retries between the POSTing user and the identity server.
     *   The client should increment this value if they desire a new
     *   email (e.g. a reminder) to be sent.
     * \param idServer
     *   The hostname of the identity server to communicate with. May
     *   optionally include a port.
     * \param nextLink
     *   Optional. When the validation is completed, the identity
     *   server will redirect the user to this URL.
     */
    explicit RequestTokenToRegisterEmailJob(const QString& clientSecret,
                                            const QString& email,
                                            int sendAttempt,
                                            const QString& idServer,
                                            const QString& nextLink = {});

    ~RequestTokenToRegisterEmailJob() override;

    // Result properties

    /// An email has been sent to the specified address.
    /// Note that this may be an email containing the validation token or it may
    /// be informing the user of an error.
    const Sid& data() const;

protected:
    Status parseJson(const QJsonDocument& data) override;

private:
    class Private;
    QScopedPointer<Private> d;
};

/// Requests a validation token be sent to the given phone number for the
/// purpose of registering an account
/*!
 * Proxies the Identity Service API ``validate/msisdn/requestToken``, but
 * first checks that the given phone number is not already associated
 * with an account on this homeserver. See the Identity Service API for
 * further information.
 */
class RequestTokenToRegisterMSISDNJob : public BaseJob
{
public:
    /*! Requests a validation token be sent to the given phone number for the
     * purpose of registering an account \param clientSecret A unique string
     * generated by the client, and used to identify the validation attempt. It
     * must be a string consisting of the characters
     *   ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it
     *   must not be empty.
     * \param country
     *   The two-letter uppercase ISO country code that the number in
     *   ``phone_number`` should be parsed as if it were dialled from.
     * \param phoneNumber
     *   The phone number to validate.
     * \param sendAttempt
     *   The server will only send an SMS if the ``send_attempt`` is a
     *   number greater than the most recent one which it has seen,
     *   scoped to that ``country`` + ``phone_number`` + ``client_secret``
     *   triple. This is to avoid repeatedly sending the same SMS in
     *   the case of request retries between the POSTing user and the
     *   identity server. The client should increment this value if
     *   they desire a new SMS (e.g. a reminder) to be sent.
     * \param idServer
     *   The hostname of the identity server to communicate with. May
     *   optionally include a port.
     * \param nextLink
     *   Optional. When the validation is completed, the identity
     *   server will redirect the user to this URL.
     */
    explicit RequestTokenToRegisterMSISDNJob(const QString& clientSecret,
                                             const QString& country,
                                             const QString& phoneNumber,
                                             int sendAttempt,
                                             const QString& idServer,
                                             const QString& nextLink = {});

    ~RequestTokenToRegisterMSISDNJob() override;

    // Result properties

    /// An SMS message has been sent to the specified phone number.
    /// Note that this may be an SMS message containing the validation token or
    /// it may be informing the user of an error.
    const Sid& data() const;

protected:
    Status parseJson(const QJsonDocument& data) override;

private:
    class Private;
    QScopedPointer<Private> d;
};

/// Changes a user's password.
/*!
 * Changes the password for an account on this homeserver.
 *
 * This API endpoint uses the `User-Interactive Authentication API`_.
 *
 * An access token should be submitted to this endpoint if the client has
 * an active session.
 *
 * The homeserver may change the flows available depending on whether a
 * valid access token is provided.
 */
class ChangePasswordJob : public BaseJob
{
public:
    /*! Changes a user's password.
     * \param newPassword
     *   The new password for the account.
     * \param auth
     *   Additional authentication information for the user-interactive
     * authentication API.
     */
    explicit ChangePasswordJob(const QString& newPassword,
                               const Omittable<AuthenticationData>& auth = none);
};

/// Requests a validation token be sent to the given email address for the
/// purpose of resetting a user's password
/*!
 * Proxies the Identity Service API ``validate/email/requestToken``, but
 * first checks that the given email address **is** associated with an account
 * on this homeserver. This API should be used to request
 * validation tokens when authenticating for the
 * `account/password` endpoint. This API's parameters and response are
 * identical to that of the HS API |/register/email/requestToken|_ except that
 * `M_THREEPID_NOT_FOUND` may be returned if no account matching the
 * given email address could be found. The server may instead send an
 * email to the given address prompting the user to create an account.
 * `M_THREEPID_IN_USE` may not be returned.
 *
 * .. |/register/email/requestToken| replace:: ``/register/email/requestToken``
 *
 * .. _/register/email/requestToken:
 * #post-matrix-client-r0-register-email-requesttoken
 */
class RequestTokenToResetPasswordEmailJob : public BaseJob
{
public:
    /*! Requests a validation token be sent to the given email address for the
     * purpose of resetting a user's password \param clientSecret A unique
     * string generated by the client, and used to identify the validation
     * attempt. It must be a string consisting of the characters
     *   ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it
     *   must not be empty.
     * \param email
     *   The email address to validate.
     * \param sendAttempt
     *   The server will only send an email if the ``send_attempt``
     *   is a number greater than the most recent one which it has seen,
     *   scoped to that ``email`` + ``client_secret`` pair. This is to
     *   avoid repeatedly sending the same email in the case of request
     *   retries between the POSTing user and the identity server.
     *   The client should increment this value if they desire a new
     *   email (e.g. a reminder) to be sent.
     * \param idServer
     *   The hostname of the identity server to communicate with. May
     *   optionally include a port.
     * \param nextLink
     *   Optional. When the validation is completed, the identity
     *   server will redirect the user to this URL.
     */
    explicit RequestTokenToResetPasswordEmailJob(const QString& clientSecret,
                                                 const QString& email,
                                                 int sendAttempt,
                                                 const QString& idServer,
                                                 const QString& nextLink = {});

    ~RequestTokenToResetPasswordEmailJob() override;

    // Result properties

    /// An email was sent to the given address.
    const Sid& data() const;

protected:
    Status parseJson(const QJsonDocument& data) override;

private:
    class Private;
    QScopedPointer<Private> d;
};

/// Requests a validation token be sent to the given phone number for the
/// purpose of resetting a user's password.
/*!
 * Proxies the Identity Service API ``validate/msisdn/requestToken``, but
 * first checks that the given phone number **is** associated with an account
 * on this homeserver. This API should be used to request
 * validation tokens when authenticating for the
 * `account/password` endpoint. This API's parameters and response are
 * identical to that of the HS API |/register/msisdn/requestToken|_ except that
 * `M_THREEPID_NOT_FOUND` may be returned if no account matching the
 * given phone number could be found. The server may instead send an
 * SMS message to the given address prompting the user to create an account.
 * `M_THREEPID_IN_USE` may not be returned.
 *
 * .. |/register/msisdn/requestToken| replace:: ``/register/msisdn/requestToken``
 *
 * .. _/register/msisdn/requestToken:
 * #post-matrix-client-r0-register-email-requesttoken
 */
class RequestTokenToResetPasswordMSISDNJob : public BaseJob
{
public:
    /*! Requests a validation token be sent to the given phone number for the
     * purpose of resetting a user's password. \param clientSecret A unique
     * string generated by the client, and used to identify the validation
     * attempt. It must be a string consisting of the characters
     *   ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it
     *   must not be empty.
     * \param country
     *   The two-letter uppercase ISO country code that the number in
     *   ``phone_number`` should be parsed as if it were dialled from.
     * \param phoneNumber
     *   The phone number to validate.
     * \param sendAttempt
     *   The server will only send an SMS if the ``send_attempt`` is a
     *   number greater than the most recent one which it has seen,
     *   scoped to that ``country`` + ``phone_number`` + ``client_secret``
     *   triple. This is to avoid repeatedly sending the same SMS in
     *   the case of request retries between the POSTing user and the
     *   identity server. The client should increment this value if
     *   they desire a new SMS (e.g. a reminder) to be sent.
     * \param idServer
     *   The hostname of the identity server to communicate with. May
     *   optionally include a port.
     * \param nextLink
     *   Optional. When the validation is completed, the identity
     *   server will redirect the user to this URL.
     */
    explicit RequestTokenToResetPasswordMSISDNJob(const QString& clientSecret,
                                                  const QString& country,
                                                  const QString& phoneNumber,
                                                  int sendAttempt,
                                                  const QString& idServer,
                                                  const QString& nextLink = {});

    ~RequestTokenToResetPasswordMSISDNJob() override;

    // Result properties

    /// An SMS message was sent to the given phone number.
    const Sid& data() const;

protected:
    Status parseJson(const QJsonDocument& data) override;

private:
    class Private;
    QScopedPointer<Private> d;
};

/// Deactivate a user's account.
/*!
 * Deactivate the user's account, removing all ability for the user to
 * login again.
 *
 * This API endpoint uses the `User-Interactive Authentication API`_.
 *
 * An access token should be submitted to this endpoint if the client has
 * an active session.
 *
 * The homeserver may change the flows available depending on whether a
 * valid access token is provided.
 */
class DeactivateAccountJob : public BaseJob
{
public:
    /*! Deactivate a user's account.
     * \param auth
     *   Additional authentication information for the user-interactive
     * authentication API.
     */
    explicit DeactivateAccountJob(
        const Omittable<AuthenticationData>& auth = none);
};

/// Checks to see if a username is available on the server.
/*!
 * Checks to see if a username is available, and valid, for the server.
 *
 * The server should check to ensure that, at the time of the request, the
 * username requested is available for use. This includes verifying that an
 * application service has not claimed the username and that the username
 * fits the server's desired requirements (for example, a server could dictate
 * that it does not permit usernames with underscores).
 *
 * Matrix clients may wish to use this API prior to attempting registration,
 * however the clients must also be aware that using this API does not normally
 * reserve the username. This can mean that the username becomes unavailable
 * between checking its availability and attempting to register it.
 */
class CheckUsernameAvailabilityJob : public BaseJob
{
public:
    /*! Checks to see if a username is available on the server.
     * \param username
     *   The username to check the availability of.
     */
    explicit CheckUsernameAvailabilityJob(const QString& username);

    /*! Construct a URL without creating a full-fledged job object
     *
     * This function can be used when a URL for
     * CheckUsernameAvailabilityJob is necessary but the job
     * itself isn't.
     */
    static QUrl makeRequestUrl(QUrl baseUrl, const QString& username);

    ~CheckUsernameAvailabilityJob() override;

    // Result properties

    /// A flag to indicate that the username is available. This should always
    /// be ``true`` when the server replies with 200 OK.
    Omittable<bool> available() const;

protected:
    Status parseJson(const QJsonDocument& data) override;

private:
    class Private;
    QScopedPointer<Private> d;
};

} // namespace Quotient