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

#pragma once

#include <Quotient/jobs/basejob.h>

#include <QtCore/QIODevice>
#include <QtNetwork/QNetworkReply>

namespace Quotient {

/*! \brief Upload some content to the content repository.
 *
 */
class QUOTIENT_API UploadContentJob : public BaseJob {
public:
    /*! \brief Upload some content to the content repository.
     *
     * \param content
     *   The content to be uploaded.
     *
     * \param filename
     *   The name of the file being uploaded
     *
     * \param contentType
     *   The content type of the file being uploaded
     */
    explicit UploadContentJob(QIODevice* content, const QString& filename = {},
                              const QString& contentType = {});

    // Result properties

    /// The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) to the
    /// uploaded content.
    QUrl contentUri() const { return loadFromJson<QUrl>("content_uri"_ls); }
};

/*! \brief Upload content to an `mxc://` URI that was created earlier.
 *
 * This endpoint permits uploading content to an `mxc://` URI that was created
 * earlier via [POST
 * /_matrix/media/v1/create](/client-server-api/#post_matrixmediav1create).
 */
class QUOTIENT_API UploadContentToMXCJob : public BaseJob {
public:
    /*! \brief Upload content to an `mxc://` URI that was created earlier.
     *
     * \param serverName
     *   The server name from the `mxc://` URI returned by `POST
     * /_matrix/media/v1/create` (the authoritory component).
     *
     * \param mediaId
     *   The media ID from the `mxc://` URI returned by `POST
     * /_matrix/media/v1/create` (the path component).
     *
     * \param content
     *   The content to be uploaded.
     *
     * \param filename
     *   The name of the file being uploaded
     *
     * \param contentType
     *   The content type of the file being uploaded
     */
    explicit UploadContentToMXCJob(const QString& serverName,
                                   const QString& mediaId, QIODevice* content,
                                   const QString& filename = {},
                                   const QString& contentType = {});
};

/*! \brief Create a new `mxc://` URI without uploading the content.
 *
 * Creates a new `mxc://` URI, independently of the content being uploaded. The
 * content must be provided later via [`PUT
 * /_matrix/media/v3/upload/{serverName}/{mediaId}`](/client-server-api/#put_matrixmediav3uploadservernamemediaid).
 *
 * The server may optionally enforce a maximum age for unused IDs,
 * and delete media IDs when the client doesn't start the upload in time,
 * or when the upload was interrupted and not resumed in time. The server
 * should include the maximum POSIX millisecond timestamp to complete the
 * upload in the `unused_expires_at` field in the response JSON. The
 * recommended default expiration is 24 hours which should be enough time
 * to accommodate users on poor connection who find a better connection to
 * complete the upload.
 *
 * As well as limiting the rate of requests to create `mxc://` URIs, the server
 * should limit the number of concurrent *pending media uploads* a given
 * user can have. A pending media upload is a created `mxc://` URI where (a)
 * the media has not yet been uploaded, and (b) has not yet expired (the
 * `unused_expires_at` timestamp has not yet passed). In both cases, the
 * server should respond with an HTTP 429 error with an errcode of
 * `M_LIMIT_EXCEEDED`.
 */
class QUOTIENT_API CreateContentJob : public BaseJob {
public:
    /// Create a new `mxc://` URI without uploading the content.
    explicit CreateContentJob();

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

    // Result properties

    /// The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) at
    /// which the content will be available, once it is uploaded.
    QUrl contentUri() const { return loadFromJson<QUrl>("content_uri"_ls); }

    /// The timestamp (in milliseconds since the unix epoch) when the
    /// generated media id will expire, if media is not uploaded.
    Omittable<qint64> unusedExpiresAt() const
    {
        return loadFromJson<Omittable<qint64>>("unused_expires_at"_ls);
    }
};

/*! \brief Download content from the content repository.
 *
 */
class QUOTIENT_API GetContentJob : public BaseJob {
public:
    /*! \brief Download content from the content repository.
     *
     * \param serverName
     *   The server name from the `mxc://` URI (the authoritory component)
     *
     * \param mediaId
     *   The media ID from the `mxc://` URI (the path component)
     *
     * \param allowRemote
     *   Indicates to the server that it should not attempt to fetch the media
     * if it is deemed remote. This is to prevent routing loops where the server
     * contacts itself. Defaults to true if not provided.
     *
     * \param timeoutMs
     *   The maximum number of milliseconds that the client is willing to
     *   wait to start receiving data, in the case that the content has not
     *   yet been uploaded. The default value is 20000 (20 seconds). The
     *   content repository can and should impose a maximum value for this
     *   parameter. The content repository may also choose to respond before
     *   the timeout.
     *
     * \param allowRedirect
     *   Indicates to the server that it may return a 307 or 308 redirect
     * response that points at the relevant media content. When not explicitly
     * set to true the server must return the media content itself.
     */
    explicit GetContentJob(const QString& serverName, const QString& mediaId,
                           bool allowRemote = true, qint64 timeoutMs = 20000,
                           bool allowRedirect = false);

    /*! \brief Construct a URL without creating a full-fledged job object
     *
     * This function can be used when a URL for GetContentJob
     * is necessary but the job itself isn't.
     */
    static QUrl makeRequestUrl(QUrl baseUrl, const QString& serverName,
                               const QString& mediaId, bool allowRemote = true,
                               qint64 timeoutMs = 20000,
                               bool allowRedirect = false);

    // Result properties

    /// The content type of the file that was previously uploaded.
    QString contentType() const
    {
        return QString::fromUtf8(reply()->rawHeader("Content-Type"));
    }

    /// The name of the file that was previously uploaded, if set.
    QString contentDisposition() const
    {
        return QString::fromUtf8(reply()->rawHeader("Content-Disposition"));
    }

    /// The content that was previously uploaded.
    QIODevice* data() { return reply(); }
};

/*! \brief Download content from the content repository overriding the file name
 *
 * This will download content from the content repository (same as
 * the previous endpoint) but replace the target file name with the one
 * provided by the caller.
 */
class QUOTIENT_API GetContentOverrideNameJob : public BaseJob {
public:
    /*! \brief Download content from the content repository overriding the file
     * name
     *
     * \param serverName
     *   The server name from the `mxc://` URI (the authoritory component)
     *
     * \param mediaId
     *   The media ID from the `mxc://` URI (the path component)
     *
     * \param fileName
     *   A filename to give in the `Content-Disposition` header.
     *
     * \param allowRemote
     *   Indicates to the server that it should not attempt to fetch the media
     * if it is deemed remote. This is to prevent routing loops where the server
     * contacts itself. Defaults to true if not provided.
     *
     * \param timeoutMs
     *   The maximum number of milliseconds that the client is willing to
     *   wait to start receiving data, in the case that the content has not
     *   yet been uploaded. The default value is 20000 (20 seconds). The
     *   content repository can and should impose a maximum value for this
     *   parameter. The content repository may also choose to respond before
     *   the timeout.
     *
     * \param allowRedirect
     *   Indicates to the server that it may return a 307 or 308 redirect
     * response that points at the relevant media content. When not explicitly
     * set to true the server must return the media content itself.
     */
    explicit GetContentOverrideNameJob(const QString& serverName,
                                       const QString& mediaId,
                                       const QString& fileName,
                                       bool allowRemote = true,
                                       qint64 timeoutMs = 20000,
                                       bool allowRedirect = false);

    /*! \brief Construct a URL without creating a full-fledged job object
     *
     * This function can be used when a URL for GetContentOverrideNameJob
     * is necessary but the job itself isn't.
     */
    static QUrl makeRequestUrl(QUrl baseUrl, const QString& serverName,
                               const QString& mediaId, const QString& fileName,
                               bool allowRemote = true, qint64 timeoutMs = 20000,
                               bool allowRedirect = false);

    // Result properties

    /// The content type of the file that was previously uploaded.
    QString contentType() const
    {
        return QString::fromUtf8(reply()->rawHeader("Content-Type"));
    }

    /// The `fileName` requested or the name of the file that was previously
    /// uploaded, if set.
    QString contentDisposition() const
    {
        return QString::fromUtf8(reply()->rawHeader("Content-Disposition"));
    }

    /// The content that was previously uploaded.
    QIODevice* data() { return reply(); }
};

/*! \brief Download a thumbnail of content from the content repository
 *
 * Download a thumbnail of content from the content repository.
 * See the [Thumbnails](/client-server-api/#thumbnails) section for more
 * information.
 */
class QUOTIENT_API GetContentThumbnailJob : public BaseJob {
public:
    /*! \brief Download a thumbnail of content from the content repository
     *
     * \param serverName
     *   The server name from the `mxc://` URI (the authoritory component)
     *
     * \param mediaId
     *   The media ID from the `mxc://` URI (the path component)
     *
     * \param width
     *   The *desired* width of the thumbnail. The actual thumbnail may be
     *   larger than the size specified.
     *
     * \param height
     *   The *desired* height of the thumbnail. The actual thumbnail may be
     *   larger than the size specified.
     *
     * \param method
     *   The desired resizing method. See the
     * [Thumbnails](/client-server-api/#thumbnails) section for more
     * information.
     *
     * \param allowRemote
     *   Indicates to the server that it should not attempt to fetch
     *   the media if it is deemed remote. This is to prevent routing loops
     *   where the server contacts itself. Defaults to true if not provided.
     *
     * \param timeoutMs
     *   The maximum number of milliseconds that the client is willing to
     *   wait to start receiving data, in the case that the content has not
     *   yet been uploaded. The default value is 20000 (20 seconds). The
     *   content repository can and should impose a maximum value for this
     *   parameter. The content repository may also choose to respond before
     *   the timeout.
     *
     * \param allowRedirect
     *   Indicates to the server that it may return a 307 or 308 redirect
     * response that points at the relevant media content. When not explicitly
     * set to true the server must return the media content itself.
     */
    explicit GetContentThumbnailJob(const QString& serverName,
                                    const QString& mediaId, int width,
                                    int height, const QString& method = {},
                                    bool allowRemote = true,
                                    qint64 timeoutMs = 20000,
                                    bool allowRedirect = false);

    /*! \brief Construct a URL without creating a full-fledged job object
     *
     * This function can be used when a URL for GetContentThumbnailJob
     * is necessary but the job itself isn't.
     */
    static QUrl makeRequestUrl(QUrl baseUrl, const QString& serverName,
                               const QString& mediaId, int width, int height,
                               const QString& method = {},
                               bool allowRemote = true, qint64 timeoutMs = 20000,
                               bool allowRedirect = false);

    // Result properties

    /// The content type of the thumbnail.
    QString contentType() const
    {
        return QString::fromUtf8(reply()->rawHeader("Content-Type"));
    }

    /// A thumbnail of the requested content.
    QIODevice* data() { return reply(); }
};

/*! \brief Get information about a URL for a client
 *
 * Get information about a URL for the client. Typically this is called when a
 * client sees a URL in a message and wants to render a preview for the user.
 *
 * **Note:**
 * Clients should consider avoiding this endpoint for URLs posted in encrypted
 * rooms. Encrypted rooms often contain more sensitive information the users
 * do not want to share with the homeserver, and this can mean that the URLs
 * being shared should also not be shared with the homeserver.
 */
class QUOTIENT_API GetUrlPreviewJob : public BaseJob {
public:
    /*! \brief Get information about a URL for a client
     *
     * \param url
     *   The URL to get a preview of.
     *
     * \param ts
     *   The preferred point in time to return a preview for. The server may
     *   return a newer version if it does not have the requested version
     *   available.
     */
    explicit GetUrlPreviewJob(const QUrl& url, Omittable<qint64> ts = none);

    /*! \brief Construct a URL without creating a full-fledged job object
     *
     * This function can be used when a URL for GetUrlPreviewJob
     * is necessary but the job itself isn't.
     */
    static QUrl makeRequestUrl(QUrl baseUrl, const QUrl& url,
                               Omittable<qint64> ts = none);

    // Result properties

    /// The byte-size of the image. Omitted if there is no image attached.
    Omittable<qint64> matrixImageSize() const
    {
        return loadFromJson<Omittable<qint64>>("matrix:image:size"_ls);
    }

    /// An [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) to the
    /// image. Omitted if there is no image.
    QUrl ogImage() const { return loadFromJson<QUrl>("og:image"_ls); }
};

/*! \brief Get the configuration for the content repository.
 *
 * This endpoint allows clients to retrieve the configuration of the content
 * repository, such as upload limitations.
 * Clients SHOULD use this as a guide when using content repository endpoints.
 * All values are intentionally left optional. Clients SHOULD follow
 * the advice given in the field description when the field is not available.
 *
 * **NOTE:** Both clients and server administrators should be aware that proxies
 * between the client and the server may affect the apparent behaviour of
 * content repository APIs, for example, proxies may enforce a lower upload size
 * limit than is advertised by the server on this endpoint.
 */
class QUOTIENT_API GetConfigJob : public BaseJob {
public:
    /// Get the configuration for the content repository.
    explicit GetConfigJob();

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

    // Result properties

    /// The maximum size an upload can be in bytes.
    /// Clients SHOULD use this as a guide when uploading content.
    /// If not listed or null, the size limit should be treated as unknown.
    Omittable<qint64> uploadSize() const
    {
        return loadFromJson<Omittable<qint64>>("m.upload.size"_ls);
    }
};

} // namespace Quotient
