/*
 * Copyright (C) 2020 by Savoir-faire Linux
 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
 * Author: Anthony Léonard <anthony.leonard@savoirfairelinux.com>
 * Author: Olivier Soldano <olivier.soldano@savoirfairelinux.com>
 * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
 * Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
 * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
 * Author: Sébastien Blin <sebastien.blin@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/>.
 */

#include "calladapter.h"

#include "globalsystemtray.h"
#include "utils.h"

CallAdapter::CallAdapter(QObject* parent)
    : QmlAdapterBase(parent)
    , oneSecondTimer_(new QTimer(this))
{}

CallAdapter::~CallAdapter() {}

void
CallAdapter::initQmlObject()
{
    connectCallModel(LRCInstance::getCurrAccId());

    connect(&LRCInstance::behaviorController(),
            &BehaviorController::showIncomingCallView,
            this,
            &CallAdapter::slotShowIncomingCallView);
    connect(&LRCInstance::instance(),
            &LRCInstance::currentAccountChanged,
            this,
            &CallAdapter::slotAccountChanged);
    connect(&LRCInstance::behaviorController(),
            &BehaviorController::showCallView,
            this,
            &CallAdapter::slotShowCallView);
}

void
CallAdapter::slotAccountChanged()
{
    connectCallModel(LRCInstance::getCurrAccId());
}

void
CallAdapter::placeAudioOnlyCall()
{
    const auto convUid = LRCInstance::getCurrentConvUid();
    if (!convUid.isEmpty()) {
        LRCInstance::getCurrentConversationModel()->placeAudioOnlyCall(convUid);
    }
}

void
CallAdapter::placeCall()
{
    const auto convUid = LRCInstance::getCurrentConvUid();
    if (!convUid.isEmpty()) {
        LRCInstance::getCurrentConversationModel()->placeCall(convUid);
    }
}

void
CallAdapter::hangUpACall(const QString& accountId, const QString& convUid)
{
    auto* convModel = LRCInstance::getCurrentConversationModel();
    const auto convInfo = convModel->getConversationForUID(convUid);
    if (!convInfo.uid.isEmpty()) {
        LRCInstance::getAccountInfo(accountId).callModel->hangUp(convInfo.callId);
    }
}

void
CallAdapter::refuseACall(const QString& accountId, const QString& convUid)
{
    auto* convModel = LRCInstance::getCurrentConversationModel();
    const auto convInfo = convModel->getConversationForUID(convUid);
    if (!convInfo.uid.isEmpty()) {
        LRCInstance::getAccountInfo(accountId).callModel->refuse(convInfo.callId);
    }
}

void
CallAdapter::acceptACall(const QString& accountId, const QString& convUid)
{
    emit incomingCallNeedToSetupMainView(accountId, convUid);
    auto* convModel = LRCInstance::getCurrentConversationModel();
    const auto convInfo = convModel->getConversationForUID(convUid);
    if (!convInfo.uid.isEmpty()) {
        LRCInstance::getAccountInfo(accountId).callModel->accept(convInfo.callId);
        auto& accInfo = LRCInstance::getAccountInfo(convInfo.accountId);
        accInfo.callModel->setCurrentCall(convInfo.callId);
    }
}

void
CallAdapter::slotShowIncomingCallView(const QString& accountId, const conversation::Info& convInfo)
{
    auto* callModel = LRCInstance::getCurrentCallModel();

    if (!callModel->hasCall(convInfo.callId)) {
        /*
         * Connection to close potential incoming call page when it is not current account.
         */
        auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId);

        QObject::disconnect(closeIncomingCallPageConnection_);

        closeIncomingCallPageConnection_
            = QObject::connect(accInfo.callModel.get(),
                               &lrc::api::NewCallModel::callStatusChanged,
                               [this, accountId, uid = convInfo.uid](const QString& callId) {
                                   auto& accInfo = LRCInstance::accountModel().getAccountInfo(
                                       accountId);
                                   auto& callModel = accInfo.callModel;
                                   auto call = callModel->getCall(callId);

                                   switch (call.status) {
                                   case lrc::api::call::Status::INVALID:
                                   case lrc::api::call::Status::INACTIVE:
                                   case lrc::api::call::Status::ENDED:
                                   case lrc::api::call::Status::PEER_BUSY:
                                   case lrc::api::call::Status::TIMEOUT:
                                   case lrc::api::call::Status::TERMINATING: {
                                       if (!uid.isEmpty())
                                           emit closePotentialIncomingCallPageWindow(accountId, uid);
                                       break;
                                   }
                                   default:
                                       break;
                                   }

                                   emit updateConversationSmartList();
                                   QObject::disconnect(closeIncomingCallPageConnection_);
                               });
        /*
         * Show incoming call page only.
         */
        auto accountProperties = LRCInstance::accountModel().getAccountConfig(accountId);
        if (!accountProperties.autoAnswer && !accountProperties.isRendezVous) {
            emit showIncomingCallPage(accountId, convInfo.uid);
        }
        return;
    }

    auto call = callModel->getCall(convInfo.callId);
    auto isCallSelected = LRCInstance::getCurrentConvUid() == convInfo.uid;

    if (call.isOutgoing) {
        if (isCallSelected) {
            emit showOutgoingCallPage(accountId, convInfo.uid);
            emit showCallStack(accountId, convInfo.uid);
        }
    } else {
        auto selectedAccountId = LRCInstance::getCurrentAccountInfo().id;
        auto accountProperties = LRCInstance::accountModel().getAccountConfig(selectedAccountId);
        if (!accountProperties.autoAnswer && !accountProperties.isRendezVous) {
            emit showIncomingCallPage(accountId, convInfo.uid);
        }
    }

    emit callStatusChanged(lrc::api::call::to_string(call.status), accountId, convInfo.uid);

    emit updateConversationSmartList();
}

void
CallAdapter::slotShowCallView(const QString& accountId, const lrc::api::conversation::Info& convInfo)
{
    updateCall(convInfo.uid, accountId);
}

void
CallAdapter::updateCall(const QString& convUid, const QString& accountId, bool forceCallOnly)
{
    accountId_ = accountId.isEmpty() ? accountId_ : accountId;
    convUid_ = convUid.isEmpty() ? convUid_ : convUid;

    auto* convModel = LRCInstance::getCurrentConversationModel();
    const auto convInfo = convModel->getConversationForUID(convUid_);
    if (convInfo.uid.isEmpty()) {
        return;
    }

    auto call = LRCInstance::getCallInfoForConversation(convInfo, forceCallOnly);
    if (!call) {
        return;
    }

    if (call->isAudioOnly) {
        emit showAudioCallPage(accountId_, convUid_);
    } else {
        emit showVideoCallPage(accountId_, convUid_, call->id);
    }

    updateCallOverlay(convInfo);

    /*
     * Preview.
     */
    emit previewVisibilityNeedToChange(shouldShowPreview(forceCallOnly));

    emit showCallStack(accountId_, convUid_);
}

bool
CallAdapter::shouldShowPreview(bool force)
{
    bool shouldShowPreview {false};
    auto* convModel = LRCInstance::getCurrentConversationModel();
    const auto convInfo = convModel->getConversationForUID(convUid_);
    if (convInfo.uid.isEmpty()) {
        return shouldShowPreview;
    }
    auto call = LRCInstance::getCallInfoForConversation(convInfo, force);
    if (call) {
        shouldShowPreview = !call->isAudioOnly && !(call->status == lrc::api::call::Status::PAUSED)
                            && !call->videoMuted && call->type != lrc::api::call::Type::CONFERENCE;
    }
    return shouldShowPreview;
}

QVariantList
CallAdapter::getConferencesInfos()
{
    QVariantList map;
    auto* convModel = LRCInstance::getCurrentConversationModel();
    const auto convInfo = convModel->getConversationForUID(convUid_);
    if (convInfo.uid.isEmpty())
        return map;
    auto callId = convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId;
    if (!callId.isEmpty()) {
        try {
            auto call = LRCInstance::getCurrentCallModel()->getCall(callId);
            for (const auto& participant : call.participantsInfos) {
                QJsonObject data;
                data["x"] = participant["x"].toInt();
                data["y"] = participant["y"].toInt();
                data["w"] = participant["w"].toInt();
                data["h"] = participant["h"].toInt();
                data["active"] = participant["active"] == "true";
                auto bestName = participant["uri"];
                auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
                data["isLocal"] = false;
                if (bestName == accInfo.profileInfo.uri) {
                    bestName = tr("me");
                    data["isLocal"] = true;
                } else {
                    try {
                        auto& contact = LRCInstance::getCurrentAccountInfo()
                                            .contactModel->getContact(participant["uri"]);
                        bestName = Utils::bestNameForContact(contact);
                    } catch (...) {
                    }
                }
                data["bestName"] = bestName;

                map.push_back(QVariant(data));
            }
            return map;
        } catch (...) {
        }
    }
    return map;
}

void
CallAdapter::connectCallModel(const QString& accountId)
{
    auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId);

    QObject::disconnect(callStatusChangedConnection_);
    QObject::disconnect(onParticipantsChangedConnection_);

    onParticipantsChangedConnection_ = QObject::connect(
        accInfo.callModel.get(),
        &lrc::api::NewCallModel::onParticipantsChanged,
        [this, accountId](const QString& confId) {
            auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId);
            auto& callModel = accInfo.callModel;
            auto call = callModel->getCall(confId);
            const auto convInfo = LRCInstance::getConversationFromCallId(confId);
            if (!convInfo.uid.isEmpty()) {
                // Convert to QML
                QVariantList map;
                for (const auto& participant : call.participantsInfos) {
                    QJsonObject data;
                    data["x"] = participant["x"].toInt();
                    data["y"] = participant["y"].toInt();
                    data["w"] = participant["w"].toInt();
                    data["h"] = participant["h"].toInt();
                    data["uri"] = participant["uri"];
                    data["active"] = participant["active"] == "true";
                    auto bestName = participant["uri"];
                    data["isLocal"] = false;
                    auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
                    if (bestName == accInfo.profileInfo.uri) {
                        bestName = tr("me");
                        data["isLocal"] = true;
                    } else {
                        try {
                            auto& contact = LRCInstance::getCurrentAccountInfo()
                                                .contactModel->getContact(participant["uri"]);
                            bestName = Utils::bestNameForContact(contact);
                        } catch (...) {
                        }
                    }
                    data["bestName"] = bestName;
                    map.push_back(QVariant(data));
                }
                emit updateParticipantsInfos(map, accountId, confId);
            }
        });

    callStatusChangedConnection_ = QObject::connect(
        accInfo.callModel.get(),
        &lrc::api::NewCallModel::callStatusChanged,
        [this, accountId](const QString& callId) {
            auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId);
            auto& callModel = accInfo.callModel;
            const auto call = callModel->getCall(callId);

            /*
             * Change status label text.
             */
            const auto convInfo = LRCInstance::getConversationFromCallId(callId);
            if (!convInfo.uid.isEmpty()) {
                emit callStatusChanged(lrc::api::call::to_string(call.status),
                                       accountId,
                                       convInfo.uid);
            }

            switch (call.status) {
            case lrc::api::call::Status::INVALID:
            case lrc::api::call::Status::INACTIVE:
            case lrc::api::call::Status::ENDED:
            case lrc::api::call::Status::PEER_BUSY:
            case lrc::api::call::Status::TIMEOUT:
            case lrc::api::call::Status::TERMINATING: {
                LRCInstance::renderer()->removeDistantRenderer(callId);
                if (convInfo.uid.isEmpty()) {
                    break;
                }
                /*
                 * If it's a conference, change the smartlist index
                 * to the next remaining participant.
                 */
                bool forceCallOnly {false};
                if (!convInfo.confId.isEmpty()) {
                    auto callList = LRCInstance::getAPI().getConferenceSubcalls(convInfo.confId);
                    if (callList.empty()) {
                        auto lastConferencee = LRCInstance::instance().popLastConferencee(
                            convInfo.confId);
                        callList.append(lastConferencee);
                        forceCallOnly = true;
                    }
                    for (const auto& callId : callList) {
                        if (!callModel->hasCall(callId)) {
                            continue;
                        }
                        auto otherConv = LRCInstance::getConversationFromCallId(callId);
                        if (!otherConv.uid.isEmpty() && otherConv.uid != convInfo.uid) {
                            /*
                             * Reset the call view corresponding accountId, uid.
                             */
                            LRCInstance::setSelectedConvId(otherConv.uid);
                            showCallStack(otherConv.accountId, otherConv.uid, true);
                            updateCall(otherConv.uid, otherConv.accountId, forceCallOnly);
                        }
                    }
                } else {
                    emit closeCallStack(accountId, convInfo.uid);
                    emit closePotentialIncomingCallPageWindow(accountId, convInfo.uid);
                }

                break;
            }
            case lrc::api::call::Status::CONNECTED:
            case lrc::api::call::Status::IN_PROGRESS: {
                const auto convInfo = LRCInstance::getConversationFromCallId(callId, accountId);
                if (!convInfo.uid.isEmpty() && convInfo.uid == LRCInstance::getCurrentConvUid()) {
                    accInfo.conversationModel->selectConversation(convInfo.uid);
                }
                LRCInstance::renderer()->addDistantRenderer(callId);
                updateCall();
                LRCInstance::getAccountInfo(accountId).callModel->setCurrentCall(callId);
                break;
            }
            case lrc::api::call::Status::PAUSED:
                updateCall();
            default:
                break;
            }

            emit updateConversationSmartList();
        });
}

void
CallAdapter::sipInputPanelPlayDTMF(const QString& key)
{
    auto callId = LRCInstance::getCallIdForConversationUid(convUid_, accountId_);
    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
        return;
    }

    LRCInstance::getCurrentCallModel()->playDTMF(callId, key);
}

/*
 * For Call Overlay
 */
void
CallAdapter::updateCallOverlay(const lrc::api::conversation::Info& convInfo)
{
    setTime(accountId_, convUid_);
    QObject::disconnect(oneSecondTimer_);
    QObject::connect(oneSecondTimer_, &QTimer::timeout, [this] { setTime(accountId_, convUid_); });
    oneSecondTimer_->start(20);
    auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);

    auto call = LRCInstance::getCallInfoForConversation(convInfo);
    if (!call) {
        return;
    }

    bool isPaused = call->status == lrc::api::call::Status::PAUSED;
    bool isAudioOnly = call->isAudioOnly && !isPaused;
    bool isAudioMuted = call->audioMuted && (call->status != lrc::api::call::Status::PAUSED);
    bool isVideoMuted = call->videoMuted && !isPaused && !call->isAudioOnly;
    bool isRecording = isRecordingThisCall();

    emit updateOverlay(isPaused,
                       isAudioOnly,
                       isAudioMuted,
                       isVideoMuted,
                       isRecording,
                       accInfo.profileInfo.type == lrc::api::profile::Type::SIP,
                       !convInfo.confId.isEmpty(),
                       Utils::bestNameForConversation(convInfo,
                                                      *LRCInstance::getCurrentConversationModel()));
}

void
CallAdapter::hangupCall(const QString& uri)
{
    const auto convInfo = LRCInstance::getConversationFromPeerUri(uri, accountId_);
    if (!convInfo.uid.isEmpty()) {
        auto callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
        if (callModel->hasCall(convInfo.callId)) {
            /*
             * Store the last remaining participant of the conference,
             * so we can switch the smartlist index after termination.
             */
            if (!convInfo.confId.isEmpty()) {
                auto callList = LRCInstance::getAPI().getConferenceSubcalls(convInfo.confId);
                if (callList.size() == 2) {
                    for (const auto& cId : callList) {
                        if (cId != convInfo.callId) {
                            LRCInstance::instance().pushLastConferencee(convInfo.confId, cId);
                        }
                    }
                }
            }

            callModel->hangUp(convInfo.callId);
        }
    }
}

void
CallAdapter::maximizeParticipant(const QString& uri, bool isActive)
{
    auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
    auto* convModel = LRCInstance::getCurrentConversationModel();
    const auto conversation = convModel->getConversationForUID(LRCInstance::getCurrentConvUid());
    const auto confId = conversation.confId;

    QString callId;
    if (LRCInstance::getCurrentAccountInfo().profileInfo.uri != uri) {
        const auto convInfo = LRCInstance::getConversationFromPeerUri(uri, accountId_);
        if (!convInfo.uid.isEmpty()) {
            callId = convInfo.callId;
        }
    }
    try {
        const auto call = callModel->getCall(confId);
        switch (call.layout) {
        case lrc::api::call::Layout::GRID:
            callModel->setActiveParticipant(confId, callId);
            callModel->setConferenceLayout(confId, lrc::api::call::Layout::ONE_WITH_SMALL);
            break;
        case lrc::api::call::Layout::ONE_WITH_SMALL:
            callModel->setActiveParticipant(confId, callId);
            callModel->setConferenceLayout(confId,
                                           isActive ? lrc::api::call::Layout::ONE
                                                    : lrc::api::call::Layout::ONE_WITH_SMALL);
            break;
        case lrc::api::call::Layout::ONE:
            callModel->setActiveParticipant(confId, callId);
            callModel->setConferenceLayout(confId, lrc::api::call::Layout::GRID);
            break;
        };
    } catch (...) {
    }
}

void
CallAdapter::minimizeParticipant()
{
    auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
    auto* convModel = LRCInstance::getCurrentConversationModel();
    const auto conversation = convModel->getConversationForUID(LRCInstance::getCurrentConvUid());
    const auto confId = conversation.confId;
    try {
        auto call = callModel->getCall(confId);
        switch (call.layout) {
        case lrc::api::call::Layout::GRID:
            break;
        case lrc::api::call::Layout::ONE_WITH_SMALL:
            callModel->setConferenceLayout(confId, lrc::api::call::Layout::GRID);
            break;
        case lrc::api::call::Layout::ONE:
            callModel->setConferenceLayout(confId, lrc::api::call::Layout::ONE_WITH_SMALL);
            break;
        };
    } catch (...) {
    }
}

void
CallAdapter::hangUpThisCall()
{
    auto* convModel = LRCInstance::getCurrentConversationModel();
    const auto convInfo = convModel->getConversationForUID(convUid_);
    if (!convInfo.uid.isEmpty()) {
        auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
        if (!convInfo.confId.isEmpty() && callModel->hasCall(convInfo.confId)) {
            callModel->hangUp(convInfo.confId);
        } else if (callModel->hasCall(convInfo.callId)) {
            callModel->hangUp(convInfo.callId);
        }
    }
}

bool
CallAdapter::isRecordingThisCall()
{
    auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
    auto& convModel = accInfo.conversationModel;
    const auto convInfo = convModel->getConversationForUID(convUid_);
    return accInfo.callModel->isRecording(convInfo.confId)
           || accInfo.callModel->isRecording(convInfo.callId);
}

bool
CallAdapter::isCurrentMaster() const
{
    auto* convModel = LRCInstance::getCurrentConversationModel();
    const auto convInfo = convModel->getConversationForUID(convUid_);
    if (!convInfo.uid.isEmpty()) {
        auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
        try {
            if (!convInfo.confId.isEmpty() && callModel->hasCall(convInfo.confId)) {
                return true;
            } else {
                auto call = callModel->getCall(convInfo.callId);
                return call.participantsInfos.size() == 0;
            }
        } catch (...) {
        }
    }
    return true;
}

int
CallAdapter::getCurrentLayoutType() const
{
    auto* convModel = LRCInstance::getCurrentConversationModel();
    const auto convInfo = convModel->getConversationForUID(convUid_);
    if (!convInfo.uid.isEmpty()) {
        auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
        try {
            auto call = callModel->getCall(convInfo.confId);
            return Utils::toUnderlyingValue(call.layout);
        } catch (...) {
        }
    }
    return -1;
}

void
CallAdapter::holdThisCallToggle()
{
    const auto callId = LRCInstance::getCallIdForConversationUid(convUid_, accountId_);
    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
        return;
    }
    auto* callModel = LRCInstance::getCurrentCallModel();
    if (callModel->hasCall(callId)) {
        callModel->togglePause(callId);
    }
    emit showOnHoldLabel(true);
}

void
CallAdapter::muteThisCallToggle()
{
    const auto callId = LRCInstance::getCallIdForConversationUid(convUid_, accountId_);
    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
        return;
    }
    auto* callModel = LRCInstance::getCurrentCallModel();
    if (callModel->hasCall(callId)) {
        callModel->toggleMedia(callId, lrc::api::NewCallModel::Media::AUDIO);
    }
}

void
CallAdapter::recordThisCallToggle()
{
    const auto callId = LRCInstance::getCallIdForConversationUid(convUid_, accountId_);
    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
        return;
    }
    auto* callModel = LRCInstance::getCurrentCallModel();
    if (callModel->hasCall(callId)) {
        callModel->toggleAudioRecord(callId);
    }
}

void
CallAdapter::videoPauseThisCallToggle()
{
    const auto callId = LRCInstance::getCallIdForConversationUid(convUid_, accountId_);
    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
        return;
    }
    auto* callModel = LRCInstance::getCurrentCallModel();
    if (callModel->hasCall(callId)) {
        callModel->toggleMedia(callId, lrc::api::NewCallModel::Media::VIDEO);
    }
    emit previewVisibilityNeedToChange(shouldShowPreview(false));
}

void
CallAdapter::setTime(const QString& accountId, const QString& convUid)
{
    const auto callId = LRCInstance::getCallIdForConversationUid(convUid, accountId);
    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
        return;
    }
    const auto callInfo = LRCInstance::getCurrentCallModel()->getCall(callId);
    if (callInfo.status == lrc::api::call::Status::IN_PROGRESS
        || callInfo.status == lrc::api::call::Status::PAUSED) {
        auto timeString = LRCInstance::getCurrentCallModel()->getFormattedCallDuration(callId);
        emit updateTimeText(timeString);
    }
}