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

  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 <tqfileinfo.h>

// TDE
#include <kservice.h>
#include <kdebug.h>

// Portal
#include "util.h"

WId parse_window_id(const TQString data)
{
    if (!data.startsWith("x11:"))
    {
        kdWarning() << "[FileChooser] Window Identifiers are currently only "
                << "supported for X11. Created dialog will be parentless."
                << endl;
        return 0;
    }

    bool ok;
    WId wid = data.mid(4).toInt(&ok, 16);
    return ok ? wid : 0;
}

ApplicationInfo application_info_from_wid(WId wid)
{
    ApplicationInfo app;
    if (wid)
    {
        // we need to get the pid but only deprecated KWin::Info has it
        KWin::Info info = KWin::info(wid);
        TQFileInfo fi(TQString("/proc/%1/exe").arg(info.pid));
        if (fi.exists() && fi.isSymLink()) {
            fi = TQFileInfo(fi.readLink());

            app.path = fi.filePath();

            // try to find corresponding desktop file
            KService::List all = KService::allServices();
            KService::List::ConstIterator svc;
            for (svc = all.begin(); svc != all.end(); ++svc) {
                TQString exec((*svc)->exec());
                if (exec.startsWith(fi.filePath()) ||
                    exec.startsWith(fi.fileName()))
                {
                    app.desktopFile = (*svc)->desktopEntryPath();
                    app.name = (*svc)->name();
                    break;
                }
            }

            // Last resort
            if (app.name.isEmpty())
                app.name = fi.fileName();
        }
    }
    return app;
}

bool check_variant(TQT_DBusVariant variant, TQString signature)
{
    return !variant.signature.isNull() && variant.signature == signature;
}

TQString bytelist_to_string(TQT_DBusDataList list)
{
    if (list.type() != TQT_DBusData::Byte) return TQString::null;
    TQCString bytes;
    TQValueList<TQ_UINT8> vl = list.toByteList();
    TQValueList<TQ_UINT8>::iterator vlit;
    for (vlit = vl.begin(); vlit != vl.end(); ++vlit)
    {
        bytes += (*vlit);
    }
    return TQString::fromLocal8Bit(bytes.data(), bytes.size());
}

TQT_DBusDataList string_to_bytelist(TQString str)
{
    TQCString bytes = str.latin1();
    TQValueList<TQ_UINT8> vl;
    char *bit;
    for (bit = bytes.begin(); bit != bytes.end(); ++bit)
    {
        vl << (TQ_UINT8)(*bit);
    }
    return TQT_DBusDataList(vl);
}

TQT_DBusDataList kurl_list_to_datalist(KURL::List urls)
{
    return TQT_DBusDataList(urls.toStringList());
}

bool make_variant(TQVariant variant, TQT_DBusVariant &other)
{
    TQString signature;
    switch (variant.type()) {
        case TQVariant::String:
        case TQVariant::Color:
        case TQVariant::Font:
        case TQVariant::Date:
        case TQVariant::DateTime:
        case TQVariant::Time:
        case TQVariant::KeySequence:
            other.signature = "s";
            other.value = TQT_DBusData::fromString(variant.toString());
            break;

        case TQVariant::Int:
            other.signature = "i";
            other.value = TQT_DBusData::fromInt32(variant.toInt());
            break;

        case TQVariant::UInt:
            other.signature = "u";
            other.value = TQT_DBusData::fromUInt32(variant.toUInt());
            break;

        case TQVariant::Double:
        case TQVariant::LongLong:
        case TQVariant::ULongLong:
            other.signature = "d";
            other.value = TQT_DBusData::fromDouble(variant.toDouble());
            break;

        case TQVariant::Bool:
            other.signature = "b";
            other.value = TQT_DBusData::fromBool(variant.toBool());
            break;

        case TQVariant::StringList:
            other.signature = "as";
            other.value = TQT_DBusData::fromList(TQT_DBusDataList(variant.toStringList()));
            break;

        default:
            if (variant.canCast(TQVariant::String)) {
                other.signature = "s";
                other.value = TQT_DBusData::fromString(variant.toString());
            }
            else {
                kdDebug() << "Cannot cast TQVariant of type " << variant.type()
                          << "to TQT_DBusVariant!" << endl;
                return false;
            }
    }
    return true;
}