/*
 * Copyright (C) 2015-2020 by Savoir-faire Linux
 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
 * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
 * Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
 * Author: Mingrui Zhang   <mingrui.zhang@savoirfairelinux.com>
 * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "version.h"

#include <string>

#include <QClipboard>
#include <QCryptographicHash>
#include <QDir>
#include <QApplication>
#include <QImage>
#include <QItemDelegate>
#include <QLabel>
#include <QListWidget>
#include <QMessageBox>
#include <QQmlEngine>
#include <QSettings>
#include <QStackedWidget>
#include <QStandardPaths>
#include <QString>
#include <QTextDocument>
#include <QtGlobal>
#include <QPainterPath>

#ifdef Q_OS_WIN
#include <ciso646>
#include <windows.h>
#undef ERROR
#else
#define LPCWSTR char *
#endif

#include "api/account.h"
#include "api/contact.h"
#include "api/contactmodel.h"
#include "api/conversationmodel.h"

static const QSize IMAGE_SIZE{128, 128};
static float CURRENT_SCALING_RATIO{1.0};

#ifdef BETA
static constexpr bool isBeta = true;
#else
static constexpr bool isBeta = false;
#endif

namespace Utils {

/*
 * Qml type register.
 */
#define QML_REGISTERSINGLETONTYPE(T, MAJ, MIN) \
    qmlRegisterSingletonType<T>("net.jami.Models", \
                                MAJ, \
                                MIN, \
                                #T, \
                                [](QQmlEngine *e, QJSEngine *se) -> QObject * { \
                                    Q_UNUSED(e); \
                                    Q_UNUSED(se); \
                                    T *obj = new T(); \
                                    return obj; \
                                });
#define QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(T, MAJ, MIN) \
    qmlRegisterSingletonType<T>("net.jami.Models", \
                                MAJ, \
                                MIN, \
                                #T, \
                                [](QQmlEngine *e, QJSEngine *se) -> QObject * { \
                                    Q_UNUSED(e); \
                                    Q_UNUSED(se); \
                                    return &(T::instance()); \
                                });

#define QML_REGISTERSINGLETONTYPE_URL(URL, T, MAJ, MIN) \
    qmlRegisterSingletonType(QUrl(URL), "net.jami.Models", MAJ, MIN, #T);

#define QML_REGISTERTYPE(T, MAJ, MIN) qmlRegisterType<T>("net.jami.Models", MAJ, MIN, #T);

#define QML_REGISTERNAMESPACE(T, NAME, MAJ, MIN) \
    qmlRegisterUncreatableMetaObject(T, "net.jami.Models", MAJ, MIN, NAME, "")

#define QML_REGISTERUNCREATABLE(T, MAJ, MIN) \
    qmlRegisterUncreatableType<T>("net.jami.Models", \
                                  MAJ, \
                                  MIN, \
                                  #T, \
                                  "Don't try to add to a qml definition of " #T);

#define QML_REGISTERUNCREATABLE_IN_NAMESPACE(T, NAMESPACE, MAJ, MIN) \
    qmlRegisterUncreatableType<NAMESPACE::T>("net.jami.Models", \
                                             MAJ, \
                                             MIN, \
                                             #T, \
                                             "Don't try to add to a qml definition of " #T);

/*
 * System.
 */
bool CreateStartupLink(const std::wstring &wstrAppName);
void DeleteStartupLink(const std::wstring &wstrAppName);
bool CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszPathLink);
bool CheckStartupLink(const std::wstring &wstrAppName);
void removeOldVersions();
const char *WinGetEnv(const char *name);
QString GetRingtonePath();
QString GenGUID();
QString GetISODate();
void InvokeMailto(const QString &subject,
                  const QString &body,
                  const QString &attachement = QString());
void setStackWidget(QStackedWidget *stack, QWidget *widget);
void showSystemNotification(QWidget *widget,
                            const QString &message,
                            long delay = 5000,
                            const QString &triggeredAccountId = "");
void showSystemNotification(QWidget *widget,
                            const QString &sender,
                            const QString &message,
                            long delay = 5000,
                            const QString &triggeredAccountId = "");
QSize getRealSize(QScreen *screen);
void forceDeleteAsync(const QString &path);
QString getChangeLog();
QString getProjectCredits();
float getCurrentScalingRatio();
void setCurrentScalingRatio(float ratio);

/*
 * Updates.
 */
void cleanUpdateFiles();
void checkForUpdates(bool withUI, QWidget *parent = nullptr);
void applyUpdates(bool updateToBeta, QWidget *parent = nullptr);

/*
 * Names.
 */
QString bestIdForConversation(const lrc::api::conversation::Info &conv,
                              const lrc::api::ConversationModel &model);
QString bestIdForAccount(const lrc::api::account::Info &account);
QString bestNameForAccount(const lrc::api::account::Info &account);
QString bestIdForContact(const lrc::api::contact::Info &contact);
QString bestNameForContact(const lrc::api::contact::Info &contact);
QString bestNameForConversation(const lrc::api::conversation::Info &conv,
                                const lrc::api::ConversationModel &model);
/*
 * Returns empty string if only infoHash is available.
 */
QString secondBestNameForAccount(const lrc::api::account::Info &account);
lrc::api::profile::Type profileType(const lrc::api::conversation::Info &conv,
                                    const lrc::api::ConversationModel &model);

/*
 * Interactions.
 */
std::string formatTimeString(const std::time_t &timestamp);
bool isInteractionGenerated(const lrc::api::interaction::Type &interaction);
bool isContactValid(const QString &contactUid, const lrc::api::ConversationModel &model);
bool getReplyMessageBox(QWidget *widget, const QString &title, const QString &text);

/*
 * Image.
 */
QString getContactImageString(const QString &accountId, const QString &uid);
QImage getCirclePhoto(const QImage original, int sizePhoto);
QImage conversationPhoto(const QString &convUid,
                         const lrc::api::account::Info &accountInfo,
                         bool filtered = false);
QColor getAvatarColor(const QString &canonicalUri);
QImage fallbackAvatar(const QSize size,
                      const QString &canonicalUriStr,
                      const QString &letterStr = QString());
QImage fallbackAvatar(const QSize size, const std::string &alias, const std::string &uri);
QByteArray QImageToByteArray(QImage image);
QByteArray QByteArrayFromFile(const QString &filename);
QPixmap generateTintedPixmap(const QString &filename, QColor color);
QPixmap generateTintedPixmap(const QPixmap &pix, QColor color);
QImage scaleAndFrame(const QImage photo, const QSize &size = IMAGE_SIZE);
QImage accountPhoto(const lrc::api::account::Info &accountInfo, const QSize &size = IMAGE_SIZE);
QImage cropImage(const QImage &img);
QPixmap pixmapFromSvg(const QString &svg_resource, const QSize &size);
QImage setupQRCode(QString ringID, int margin);

/*
 * Rounded corner.
 */
template<typename T>
void
fillRoundRectPath(QPainter &painter,
                  const T &brushType,
                  const QRect &rectToDraw,
                  qreal cornerRadius,
                  int xTransFormOffset = 0,
                  int yTransFormOffset = 0)
{
    QBrush brush(brushType);
    brush.setTransform(QTransform::fromTranslate(rectToDraw.x() + xTransFormOffset,
                                                 rectToDraw.y() + yTransFormOffset));
    QPainterPath painterPath;
    painterPath.addRoundRect(rectToDraw, cornerRadius);
    painter.fillPath(painterPath, brush);
}

/*
 * Time.
 */
QString formattedTime(int seconds);

/*
 * Byte to human readable size.
 */
QString humanFileSize(qint64 fileSize);

/*
 * Device plug or unplug enum.
 */
enum class DevicePlugStatus { Plugged, Unplugged, Unchanged };

class OneShotDisconnectConnection : public QObject
{
    Q_OBJECT

public:
    explicit OneShotDisconnectConnection(const QObject *sender,
                                         const char *signal,
                                         QMetaObject::Connection *connection,
                                         QObject *parent = nullptr)
        : QObject(parent)
    {
        connection_ = connection;
        disconnectConnection_ = new QMetaObject::Connection;
        *disconnectConnection_ = QObject::connect(sender,
                                                  signal,
                                                  this,
                                                  SLOT(slotOneShotDisconnectConnection()));
    }
    ~OneShotDisconnectConnection()
    {
        if (!connection_) {
            delete connection_;
        }
        if (!disconnectConnection_) {
            delete disconnectConnection_;
        }
        if (!this) {
            delete this;
        }
    }

public slots:
    void
    slotOneShotDisconnectConnection()
    {
        if (connection_) {
            QObject::disconnect(*connection_);
            delete connection_;
        }
        if (disconnectConnection_) {
            QObject::disconnect(*disconnectConnection_);
            delete disconnectConnection_;
        }
        delete this;
    }

private:
    QMetaObject::Connection *connection_;
    QMetaObject::Connection *disconnectConnection_;
};

template<typename Func1, typename Func2>
void
oneShotConnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender,
               Func1 signal,
               Func2 slot)
{
    QMetaObject::Connection *const connection = new QMetaObject::Connection;
    *connection = QObject::connect(sender, signal, slot);
    QMetaObject::Connection *const disconnectConnection = new QMetaObject::Connection;
    *disconnectConnection = QObject::connect(sender, signal, [connection, disconnectConnection] {
        if (connection) {
            QObject::disconnect(*connection);
            delete connection;
        }
        if (disconnectConnection) {
            QObject::disconnect(*disconnectConnection);
            delete disconnectConnection;
        }
    });
}

template<typename Func1, typename Func2>
void
oneShotConnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender,
               Func1 signal,
               const typename QtPrivate::FunctionPointer<Func2>::Object *receiver,
               Func2 slot)
{
    QMetaObject::Connection *const connection = new QMetaObject::Connection;
    *connection = QObject::connect(sender, signal, receiver, slot);
    QMetaObject::Connection *const disconnectConnection = new QMetaObject::Connection;
    *disconnectConnection = QObject::connect(sender, signal, [connection, disconnectConnection] {
        if (connection) {
            QObject::disconnect(*connection);
            delete connection;
        }
        if (disconnectConnection) {
            QObject::disconnect(*disconnectConnection);
            delete disconnectConnection;
        }
    });
}

inline void
oneShotConnect(const QObject *sender, const char *signal, const QObject *receiver, const char *slot)
{
    QMetaObject::Connection *const connection = new QMetaObject::Connection;
    *connection = QObject::connect(sender, signal, receiver, slot);
    OneShotDisconnectConnection *disconnectConnection = new OneShotDisconnectConnection(sender,
                                                                                        signal,
                                                                                        connection);
    Q_UNUSED(disconnectConnection)
}

template<class T>
class Blocker
{
    T *blocked;
    bool previous;

public:
    Blocker(T *blocked)
        : blocked(blocked)
        , previous(blocked->blockSignals(true))
    {}
    ~Blocker() { blocked->blockSignals(previous); }
    T *
    operator->()
    {
        return blocked;
    }
};

template<class T>
inline Blocker<T>
whileBlocking(T *blocked)
{
    return Blocker<T>(blocked);
}

template<typename T>
void
setElidedText(T *object,
              const QString &text,
              Qt::TextElideMode mode = Qt::ElideMiddle,
              int padding = 32)
{
    QFontMetrics metrics(object->font());
    QString clippedText = metrics.elidedText(text, mode, object->width() - padding);
    object->setText(clippedText);
}

template<typename E>
constexpr inline
    typename std::enable_if<std::is_enum<E>::value, typename std::underlying_type<E>::type>::type
    toUnderlyingValue(E e) noexcept
{
    return static_cast<typename std::underlying_type<E>::type>(e);
}

template<typename E, typename T>
constexpr inline
    typename std::enable_if<std::is_enum<E>::value && std::is_integral<T>::value, E>::type
    toEnum(T value) noexcept
{
    return static_cast<E>(value);
}
} // namespace Utils

class UtilsAdapter : public QObject
{
    Q_OBJECT
public:
    explicit UtilsAdapter(QObject *parent = nullptr)
        : QObject(parent)
    {
        clipboard_ = QApplication::clipboard();
    }
    ~UtilsAdapter() {}

    ///Singleton
    static UtilsAdapter &instance();

    Q_INVOKABLE const QString
    getChangeLog()
    {
        return Utils::getChangeLog();
    }

    Q_INVOKABLE const QString
    getProjectCredits()
    {
        return Utils::getProjectCredits();
    }

    Q_INVOKABLE const QString
    getVersionStr()
    {
        return QString(VERSION_STRING);
    }

    Q_INVOKABLE void
    setText(QString text)
    {
        clipboard_->setText(text, QClipboard::Clipboard);
    }

    Q_INVOKABLE const QString
    qStringFromFile(const QString &filename)
    {
        return Utils::QByteArrayFromFile(filename);
    }

    Q_INVOKABLE const QString
    getStyleSheet(const QString &name, const QString &source)
    {
        auto simplifiedCSS = source.simplified().replace("'", "\"");
        QString s = QString::fromLatin1("(function() {"
                                        "    var node = document.createElement('style');"
                                        "    node.id = '%1';"
                                        "    node.innerHTML = '%2';"
                                        "    document.head.appendChild(node);"
                                        "})()")
                        .arg(name)
                        .arg(simplifiedCSS);
        return s;
    }

    Q_INVOKABLE const QString
    getCachePath()
    {
        QDir dataDir(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
        dataDir.cdUp();
        return dataDir.absolutePath() + "/jami";
    }
    Q_INVOKABLE bool
    createStartupLink()
    {
        return Utils::CreateStartupLink(L"Jami");
    }
    Q_INVOKABLE QString
    GetRingtonePath()
    {
        return Utils::GetRingtonePath();
    }
    Q_INVOKABLE bool
    checkStartupLink()
    {
        return Utils::CheckStartupLink(L"Jami");
    }

    Q_INVOKABLE const QString
    getContactImageString(const QString &accountId, const QString &uid)
    {
        return Utils::getContactImageString(accountId, uid);
    }

    Q_INVOKABLE void removeConversation(const QString &accountId,
                                        const QString &uid,
                                        bool banContact = false);
    Q_INVOKABLE void clearConversationHistory(const QString &accountId, const QString &uid);
    Q_INVOKABLE void setConversationFilter(const QString &filter);
    Q_INVOKABLE int getTotalUnreadMessages();
    Q_INVOKABLE int getTotalPendingRequest();
    Q_INVOKABLE const QString getBestName(const QString &accountId, const QString &uid);
    Q_INVOKABLE const QString getBestId(const QString &accountId, const QString &uid);

    Q_INVOKABLE const QString getCurrAccId();
    Q_INVOKABLE const QStringList getCurrAccList();
    Q_INVOKABLE int getAccountListSize();
    Q_INVOKABLE void setCurrentCall(const QString &accountId, const QString &convUid);
    Q_INVOKABLE void startPreviewing(bool force);
    Q_INVOKABLE void stopPreviewing();
    Q_INVOKABLE bool hasVideoCall();
    Q_INVOKABLE const QString getCallId(const QString &accountId, const QString &convUid);
    Q_INVOKABLE QString getStringUTF8(QString string);
    Q_INVOKABLE bool validateRegNameForm(const QString &regName);
    Q_INVOKABLE QString getRecordQualityString(int value);
    Q_INVOKABLE QString getCurrentPath();
    Q_INVOKABLE QString
    stringSimplifier(QString input)
    {
        return input.simplified();
    }

    Q_INVOKABLE QString
    toNativeSeparators(QString inputDir)
    {
        return QDir::toNativeSeparators(inputDir);
    }

    Q_INVOKABLE QString
    toFileInfoName(QString inputFileName)
    {
        QFileInfo fi(inputFileName);
        return fi.fileName();
    }

    Q_INVOKABLE QString
    toFileAbsolutepath(QString inputFileName)
    {
        QFileInfo fi(inputFileName);
        return fi.absolutePath();
    }

    Q_INVOKABLE QString
    getAbsPath(QString path)
    {
#ifdef Q_OS_WIN
        return path.replace("file:///", "").replace("\n", "").replace("\r", "");
#else
        return path.replace("file:///", "/").replace("\n", "").replace("\r", "");
#endif
    }

    Q_INVOKABLE QString
    getCroppedImageBase64FromFile(QString fileName, int size)
    {
        auto image = Utils::cropImage(QImage(fileName));
        auto croppedImage = image.scaled(size,
                                         size,
                                         Qt::KeepAspectRatioByExpanding,
                                         Qt::SmoothTransformation);
        return QString::fromLatin1(Utils::QImageToByteArray(croppedImage).toBase64().data());
    }

    Q_INVOKABLE bool checkShowPluginsButton();

private:
    QClipboard *clipboard_;
};
Q_DECLARE_METATYPE(UtilsAdapter *)
