/*
 * SPDX-FileCopyrightText: Copyright 2023-2024 Open Mobile Platform LLC <community@omp.ru>
 * SPDX-License-Identifier: Proprietary
 */

#pragma once

#include "enums/types.h"
#include <memory>

#include <QObject>
#include <QString>

namespace Aurora {
namespace WebView {

class DownloadItemInternal;

/**
 * @class DownloadItem
 * @brief Represents a state of download at a particular moment in time.
 *
 * Do not expect fields of a specific DownloadItem instance to be updated!
 * Each download state update produces a new DownloadItem with updated fields!
 */
class DownloadItem
{
    Q_GADGET

    /// All DownloadItems related to the same download have identical IDs
    Q_PROPERTY(quint32 id READ id)

    /// Returns CEF_DOWNLOAD_INTERRUPT_REASON_NONE if everything is fine
    Q_PROPERTY(qint32 interruptCode READ interruptCode)
    /// total size in bytes
    Q_PROPERTY(qint64 totalBytes READ totalBytes)
    /// returns -1 if total size is unknown
    Q_PROPERTY(qint32 percentComplete READ percentComplete)

    /// bytes received
    Q_PROPERTY(qint64 receivedBytes READ receivedBytes)
    /// current speed in bytes/s
    Q_PROPERTY(qint64 currentSpeed READ currentSpeed)
    /// full path to the file
    Q_PROPERTY(QString fullPath READ fullPath)
    /// url of the file
    Q_PROPERTY(QString url READ url)
    /// original url (before redirects)
    Q_PROPERTY(QString originalURL READ originalURL)
    /// content disposition
    Q_PROPERTY(QString contentDisposition READ contentDisposition)
    /// mime type of the file
    Q_PROPERTY(QString mimeType READ mimeType)

    /// returns true if DownloadItem is valid. Do not use if false
    Q_PROPERTY(bool isValid READ isValid)
    /// true if the download is in progress
    Q_PROPERTY(bool isInProgress READ isInProgress)
    /// true if the download is complete
    Q_PROPERTY(bool isComplete READ isComplete)
    /// true if the download was canceled
    Q_PROPERTY(bool isCanceled READ isCanceled)
    /// true if the download was interrupted
    Q_PROPERTY(bool isInterrupted READ isInterrupted)
public:
    /**
     * @brief Constructs a new Download Item object
     * This constructor is declared to register
     * this class in QML
     */
    DownloadItem();
    DownloadItem(const DownloadItem &other) = default;
    /**
     * @brief Destroys the Download Item object
     */
    virtual ~DownloadItem() = default;

    /// cancels the download
    Q_INVOKABLE virtual void cancel();
    /// pauses the download
    Q_INVOKABLE virtual void pause();
    /// resumes the paused download
    Q_INVOKABLE virtual void resume();

    /**
     * @brief accepts a new download
     *
     * @param absolutePath save location (absolute path including the filename.extension)
     */
    Q_INVOKABLE virtual void accept(QString absolutePath);

    quint32 id() const;
    qint32 interruptCode() const; // Returns CEF_DOWNLOAD_INTERRUPT_REASON_NONE
                                  // if everything is fine
    qint64 totalBytes() const;
    qint32 percentComplete() const; // Returns -1 if total size is unknown
    qint64 receivedBytes() const;
    qint64 currentSpeed() const; // bytes/s
    QString fullPath() const;
    QString url() const;
    QString originalURL() const;
    QString contentDisposition() const;
    QString mimeType() const;

    bool isValid() const;
    bool isInProgress() const;
    bool isComplete() const;
    bool isCanceled() const;
    bool isInterrupted() const;

private:
    DownloadItem(std::shared_ptr<DownloadItemInternal> downloadItemInternal);

    std::shared_ptr<DownloadItemInternal> m_d;

    friend class DownloadItemInternal;
};

} // namespace WebView
} // namespace Aurora

Q_DECLARE_METATYPE(Aurora::WebView::DownloadItem)
