/*******************************************************************************
  XDG desktop portal implementation for TDE
  Copyright © 2024 Mavridis Philippe <mavridisf@gmail.com>

  Avatar detection code is based on code from the Redmond KSplash theme
  Copyright © 2001-2003 Brian Ledbetter 2001-2003 <brian@shadowcom.net>
  Copyright © 2003 Ravikiran Rajagopal 2003 <ravi@kde.org>

  This program or library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public License as
  published by the Free Software Foundation; either version 2.1 of the License,
  or (at your option) any later version.

  This library 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 Lesser General Public License for more
  details.

  You should have received a copy of the GNU Lesser General Public License
  along with this library; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

  Improvements and feedback are welcome!
*******************************************************************************/

// TQt
#include <tqfile.h>
#include <tqhbox.h>
#include <tqlabel.h>
#include <tqdbusdata.h>

// TDE
#include <kstandarddirs.h>
#include <ksimpleconfig.h>
#include <tdelocale.h>
#include <twin.h>
#include <kuser.h>
#include <kdebug.h>

// Portal
#include "permission_dialog.h"
#include "account_portal.h"
#include "account_portal.moc"

#define TQSTRING_TO_DBUS_VARIANT(x) \
    TQT_DBusData::fromString(x).getAsVariantData().toVariant()

TDEAccountPortal::TDEAccountPortal(TQT_DBusConnection &connection)
: m_connection(connection)
{
    // Get account information
    KUser user;
    m_info.userId = TQString::number(user.uid());
    m_info.loginName = user.loginName();
    m_info.realName = user.fullName();
    m_info.homeDirectory = user.homeDir();

    // -- Find user avatar
    // Parse tdmrc settings to determine face source and system location
    const int fAdminOnly  = 1;
    const int fAdminFirst = fAdminOnly  + 1;
    const int fUserFirst  = fAdminFirst + 1;
    const int fUserOnly   = fUserFirst  + 1;

    int faceSource = fAdminOnly;
    TDEConfig *tdmconfig = new TDEConfig("tdm/tdmrc", true);
    tdmconfig->setGroup("X-*-Greeter");

    TQString fs = tdmconfig->readEntry("FaceSource");
    if (fs == TQString::fromLatin1("UserOnly"))
        faceSource = fUserOnly;
    else if (fs == TQString::fromLatin1("PreferUser"))
        faceSource = fUserFirst;
    else if (fs == TQString::fromLatin1("PreferAdmin"))
        faceSource = fAdminFirst;
    else
        faceSource = fAdminOnly;

    TQString userPicsDir = tdmconfig->readEntry("FaceDir",
        TDEGlobal::dirs()->resourceDirs("data").last() + "tdm/faces") + '/';

    delete tdmconfig;

    // Faces provided by administrator (default and per user)
    const TQString systemDefault(userPicsDir + ".default.face.icon");
    const TQString systemUser(userPicsDir + m_info.loginName + ".face.icon");

    TQString avatar;
    if (faceSource == fAdminFirst)
    {
        avatar = systemUser;
        if (!TQFile::exists(avatar))
            faceSource = fUserOnly;
    }

    if (faceSource >= fUserFirst)
    {
        avatar = m_info.homeDirectory + "/.face.icon";
        if (!TQFile::exists(avatar) && faceSource == fUserFirst)
            avatar = systemUser;

        if (!TQFile::exists(avatar))
            avatar = systemDefault;
    }

    if (faceSource <= fAdminOnly)
    {
        avatar = systemUser;
        if (!TQFile::exists(avatar))
            avatar = systemDefault;
    }

    m_info.avatarPath = avatar;
}

TDEAccountPortal::~TDEAccountPortal()
{
}

void TDEAccountPortal::handleMethodReply(const TQT_DBusMessage &reply)
{
    m_connection.send(reply);
}

bool TDEAccountPortal::handleSignalSend(const TQT_DBusMessage& reply) {
    handleMethodReply(reply);
    return true;
}

void TDEAccountPortal::GetUserInformationAsync(int asyncCallId,
                                               const TQT_DBusObjectPath& handle,
                                               const TQString& app_id,
                                               const TQString& window,
                                               const TQT_DBusVariantMap& options)
{
    Dictionary details;

    if (OPTION_VALID("reason", "s"))
    {
        TQString reason(options["reason"].value.toString());
        if (!reason.isEmpty())
        {
            details[i18n("Reason")] = reason;
        }
    }

    // Try to detect which application requested the permission
    WId wid = parse_window_id(window);
    ApplicationInfo app = application_info_from_wid(wid);

    if (!app.path.isEmpty())
        details[i18n("Path")] = app.path;

    // Run the dialog
    TDEPermissionDialog *dialog = new TDEPermissionDialog(
        app.name,
        i18n("Account information"),
        "user-info",
        details
    );
    appendDataPreview(dialog, m_info);

    if (wid > 0) KWin::setMainWindow(dialog, wid);

    auto *sender = new DialogResultSender<TDEAccountPortal>
        (this, asyncCallId, dialog,
         &TDEAccountPortal::prepareReply,
         &TDEAccountPortal::GetUserInformationAsyncReply);
    dialog->show();
    sender->start();
}

DialogResult TDEAccountPortal::prepareReply(TQDialog *dlg)
{
    DialogResult res;
    if (dlg->result() == KDialogBase::Yes)
    {
        res.response = 0;
        res.results.insert("id", TQSTRING_TO_DBUS_VARIANT(m_info.userId));
        res.results.insert("name", TQSTRING_TO_DBUS_VARIANT(m_info.realName));
        res.results.insert("image", TQSTRING_TO_DBUS_VARIANT(m_info.avatarPath));
    }
    else
    {
        res.response = 1;
    }
    return res;
}

void TDEAccountPortal::appendDataPreview(TDEPermissionDialog *dlg, AccountInfo info)
{
    TQHBox *frame = new TQHBox(dlg);
    frame->setFrameStyle(TQFrame::StyledPanel | TQFrame::Sunken);

    TQLabel *avatar = new TQLabel(frame);
    avatar->setPixmap(TQPixmap(info.avatarPath));

    TQString userDataStr = "<qt><h1>%1</h1><hr>ID: %2</qt>";
    userDataStr = userDataStr.arg(info.realName, info.userId);
    TQLabel *userData = new TQLabel(userDataStr, frame);

    avatar->setMargin(TDEPermissionDialog::spacingHint());
    userData->setMargin(TDEPermissionDialog::spacingHint());

    frame->setSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::Fixed);

    dlg->appendWidget(frame);
}

// kate: replace-tabs true; tab-width 4; indent-width 4;