/****************************************************************************
**
** Copyright (C) 2013 Teo Mrnjavac <teo@kde.org>
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qxcbsessionmanager.h"

#ifndef QT_NO_SESSIONMANAGER

#include <qpa/qwindowsysteminterface.h>

#include <qguiapplication.h>
#include <qdatetime.h>
#include <qfileinfo.h>
#include <qplatformdefs.h>
#include <qsocketnotifier.h>
#include <X11/SM/SMlib.h>
#include <errno.h> // ERANGE

#include <cerrno> // ERANGE

class QSmSocketReceiver : public QObject
{
    Q_OBJECT
public:
    QSmSocketReceiver(int socket)
    {
        QSocketNotifier* sn = new QSocketNotifier(socket, QSocketNotifier::Read, this);
        connect(sn, SIGNAL(activated(QSocketDescriptor)), this, SLOT(socketActivated()));
    }

public Q_SLOTS:
     void socketActivated();
};


static SmcConn smcConnection = nullptr;
static bool sm_interactionActive;
static bool sm_smActive;
static int sm_interactStyle;
static int sm_saveType;
static bool sm_cancel;
static bool sm_waitingForInteraction;
static bool sm_isshutdown;
static bool sm_phase2;
static bool sm_in_phase2;
bool qt_sm_blockUserInput = false;

static QSmSocketReceiver* sm_receiver = nullptr;

static void resetSmState();
static void sm_setProperty(const char *name, const char *type,
                            int num_vals, SmPropValue *vals);
static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
                                  int saveType, Bool shutdown , int interactStyle, Bool fast);
static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData) ;
static void sm_dieCallback(SmcConn smcConn, SmPointer clientData) ;
static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData);
static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer clientData);
static void sm_interactCallback(SmcConn smcConn, SmPointer clientData);
static void sm_performSaveYourself(QXcbSessionManager*);

static void resetSmState()
{
    sm_waitingForInteraction = false;
    sm_interactionActive = false;
    sm_interactStyle = SmInteractStyleNone;
    sm_smActive = false;
    qt_sm_blockUserInput = false;
    sm_isshutdown = false;
    sm_phase2 = false;
    sm_in_phase2 = false;
}


// theoretically it's possible to set several properties at once. For
// simplicity, however, we do just one property at a time
static void sm_setProperty(const char *name, const char *type,
                            int num_vals, SmPropValue *vals)
{
    if (num_vals) {
      SmProp prop;
      prop.name = const_cast<char*>(name);
      prop.type = const_cast<char*>(type);
      prop.num_vals = num_vals;
      prop.vals = vals;

      SmProp* props[1];
      props[0] = &prop;
      SmcSetProperties(smcConnection, 1, props);
    } else {
      char* names[1];
      names[0] = const_cast<char*>(name);
      SmcDeleteProperties(smcConnection, 1, names);
    }
}

static void sm_setProperty(const QString &name, const QString &value)
{
    QByteArray v = value.toUtf8();
    SmPropValue prop;
    prop.length = v.length();
    prop.value = (SmPointer) const_cast<char *>(v.constData());
    sm_setProperty(name.toLatin1().data(), SmARRAY8, 1, &prop);
}

static void sm_setProperty(const QString &name, const QStringList &value)
{
    SmPropValue *prop = new SmPropValue[value.count()];
    int count = 0;
    QList<QByteArray> vl;
    vl.reserve(value.size());
    for (QStringList::ConstIterator it = value.begin(); it != value.end(); ++it) {
      prop[count].length = (*it).length();
      vl.append((*it).toUtf8());
      prop[count].value = (char*)vl.constLast().data();
      ++count;
    }
    sm_setProperty(name.toLatin1().data(), SmLISTofARRAY8, count, prop);
    delete [] prop;
}


// workaround for broken libsm, see below
struct QT_smcConn {
    unsigned int save_yourself_in_progress : 1;
    unsigned int shutdown_in_progress : 1;
};

static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
                                  int saveType, Bool shutdown , int interactStyle, Bool /*fast*/)
{
    if (smcConn != smcConnection)
        return;
    sm_cancel = false;
    sm_smActive = true;
    sm_isshutdown = shutdown;
    sm_saveType = saveType;
    sm_interactStyle = interactStyle;

    // ugly workaround for broken libSM. libSM should do that _before_
    // actually invoking the callback in sm_process.c
    ((QT_smcConn*)smcConn)->save_yourself_in_progress = true;
    if (sm_isshutdown)
        ((QT_smcConn*)smcConn)->shutdown_in_progress = true;

    sm_performSaveYourself((QXcbSessionManager*) clientData);
    if (!sm_isshutdown) // we cannot expect a confirmation message in that case
        resetSmState();
}

static void sm_performSaveYourself(QXcbSessionManager *sm)
{
    if (sm_isshutdown)
        qt_sm_blockUserInput = true;

    // generate a new session key
    timeval tv;
    gettimeofday(&tv, nullptr);
    sm->setSessionKey(QString::number(qulonglong(tv.tv_sec)) +
                      QLatin1Char('_') +
                      QString::number(qulonglong(tv.tv_usec)));

    QStringList arguments = QCoreApplication::arguments();
    QString argument0 = arguments.isEmpty() ? QCoreApplication::applicationFilePath()
                                            : arguments.at(0);

    // tell the session manager about our program in best POSIX style
    sm_setProperty(QString::fromLatin1(SmProgram), argument0);
    // tell the session manager about our user as well.
    struct passwd *entryPtr = nullptr;
#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
    QVarLengthArray<char, 1024> buf(qMax<long>(sysconf(_SC_GETPW_R_SIZE_MAX), 1024L));
    struct passwd entry;
    while (getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr) == ERANGE) {
        if (buf.size() >= 32768) {
            // too big already, fail
            static char badusername[] = "";
            entryPtr = &entry;
            entry.pw_name = badusername;
            break;
        }

        // retry with a bigger buffer
        buf.resize(buf.size() * 2);
    }
#else
    entryPtr = getpwuid(geteuid());
#endif
    if (entryPtr)
        sm_setProperty(QString::fromLatin1(SmUserID), QString::fromLocal8Bit(entryPtr->pw_name));

    // generate a restart and discard command that makes sense
    QStringList restart;
    restart  << argument0 << QLatin1String("-session")
             << sm->sessionId() + QLatin1Char('_') + sm->sessionKey();

    QFileInfo fi = QCoreApplication::applicationFilePath();
    if (qAppName().compare(fi.fileName(), Qt::CaseInsensitive) != 0)
        restart << QLatin1String("-name") << qAppName();
    sm->setRestartCommand(restart);
    QStringList discard;
    sm->setDiscardCommand(discard);

    switch (sm_saveType) {
    case SmSaveBoth:
        sm->appCommitData();
        if (sm_isshutdown && sm_cancel)
            break; // we cancelled the shutdown, no need to save state
    // fall through
    case SmSaveLocal:
        sm->appSaveState();
        break;
    case SmSaveGlobal:
        sm->appCommitData();
        break;
    default:
        break;
    }

    if (sm_phase2 && !sm_in_phase2) {
        SmcRequestSaveYourselfPhase2(smcConnection, sm_saveYourselfPhase2Callback, (SmPointer*) sm);
        qt_sm_blockUserInput = false;
    } else {
        // close eventual interaction monitors and cancel the
        // shutdown, if required. Note that we can only cancel when
        // performing a shutdown, it does not work for checkpoints
        if (sm_interactionActive) {
            SmcInteractDone(smcConnection, sm_isshutdown && sm_cancel);
            sm_interactionActive = false;
        } else if (sm_cancel && sm_isshutdown) {
            if (sm->allowsErrorInteraction()) {
                SmcInteractDone(smcConnection, True);
                sm_interactionActive = false;
            }
        }

        // set restart and discard command in session manager
        sm_setProperty(QString::fromLatin1(SmRestartCommand), sm->restartCommand());
        sm_setProperty(QString::fromLatin1(SmDiscardCommand), sm->discardCommand());

        // set the restart hint
        SmPropValue prop;
        prop.length = sizeof(int);
        int value = sm->restartHint();
        prop.value = (SmPointer) &value;
        sm_setProperty(SmRestartStyleHint, SmCARD8, 1, &prop);

        // we are done
        SmcSaveYourselfDone(smcConnection, !sm_cancel);
    }
}

static void sm_dieCallback(SmcConn smcConn, SmPointer /* clientData */)
{
    if (smcConn != smcConnection)
        return;
    resetSmState();
    QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>();
}

static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData)
{
    if (smcConn != smcConnection)
        return;
    if (sm_waitingForInteraction)
        ((QXcbSessionManager *) clientData)->exitEventLoop();
    resetSmState();
}

static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer /*clientData */)
{
    if (smcConn != smcConnection)
        return;
    resetSmState();
}

static void sm_interactCallback(SmcConn smcConn, SmPointer clientData)
{
    if (smcConn != smcConnection)
        return;
    if (sm_waitingForInteraction)
        ((QXcbSessionManager *) clientData)->exitEventLoop();
}

static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData)
{
    if (smcConn != smcConnection)
        return;
    sm_in_phase2 = true;
    sm_performSaveYourself((QXcbSessionManager *) clientData);
}


void QSmSocketReceiver::socketActivated()
{
    IceProcessMessages(SmcGetIceConnection(smcConnection), nullptr, nullptr);
}


// QXcbSessionManager starts here

QXcbSessionManager::QXcbSessionManager(const QString &id, const QString &key)
    : QPlatformSessionManager(id, key)
    , m_eventLoop(nullptr)
{
    resetSmState();
    char cerror[256];
    char* myId = nullptr;
    QByteArray b_id = id.toLatin1();
    char* prevId = b_id.data();

    SmcCallbacks cb;
    cb.save_yourself.callback = sm_saveYourselfCallback;
    cb.save_yourself.client_data = (SmPointer) this;
    cb.die.callback = sm_dieCallback;
    cb.die.client_data = (SmPointer) this;
    cb.save_complete.callback = sm_saveCompleteCallback;
    cb.save_complete.client_data = (SmPointer) this;
    cb.shutdown_cancelled.callback = sm_shutdownCancelledCallback;
    cb.shutdown_cancelled.client_data = (SmPointer) this;

    // avoid showing a warning message below
    if (!qEnvironmentVariableIsSet("SESSION_MANAGER"))
        return;

    smcConnection = SmcOpenConnection(nullptr, nullptr, 1, 0,
                                      SmcSaveYourselfProcMask |
                                      SmcDieProcMask |
                                      SmcSaveCompleteProcMask |
                                      SmcShutdownCancelledProcMask,
                                      &cb,
                                      prevId,
                                      &myId,
                                      256, cerror);

    setSessionId(QString::fromLatin1(myId));
    ::free(myId); // it was allocated by C

    QString error = QString::fromLocal8Bit(cerror);
    if (!smcConnection)
        qWarning("Qt: Session management error: %s", qPrintable(error));
    else
        sm_receiver = new QSmSocketReceiver(IceConnectionNumber(SmcGetIceConnection(smcConnection)));
}

QXcbSessionManager::~QXcbSessionManager()
{
    if (smcConnection)
        SmcCloseConnection(smcConnection, 0, nullptr);
    smcConnection = nullptr;
    delete sm_receiver;
}


void* QXcbSessionManager::handle() const
{
    return (void*) smcConnection;
}

bool QXcbSessionManager::allowsInteraction()
{
    if (sm_interactionActive)
        return true;

    if (sm_waitingForInteraction)
        return false;

    if (sm_interactStyle == SmInteractStyleAny) {
        sm_waitingForInteraction = SmcInteractRequest(smcConnection,
                                                      SmDialogNormal,
                                                      sm_interactCallback,
                                                      (SmPointer*) this);
    }
    if (sm_waitingForInteraction) {
        QEventLoop eventLoop;
        m_eventLoop = &eventLoop;
        eventLoop.exec();
        m_eventLoop = nullptr;

        sm_waitingForInteraction = false;
        if (sm_smActive) { // not cancelled
            sm_interactionActive = true;
            qt_sm_blockUserInput = false;
            return true;
        }
    }
    return false;
}

bool QXcbSessionManager::allowsErrorInteraction()
{
    if (sm_interactionActive)
        return true;

    if (sm_waitingForInteraction)
        return false;

    if (sm_interactStyle == SmInteractStyleAny || sm_interactStyle == SmInteractStyleErrors) {
        sm_waitingForInteraction = SmcInteractRequest(smcConnection,
                                                      SmDialogError,
                                                      sm_interactCallback,
                                                      (SmPointer*) this);
    }
    if (sm_waitingForInteraction) {
        QEventLoop eventLoop;
        m_eventLoop = &eventLoop;
        eventLoop.exec();
        m_eventLoop = nullptr;

        sm_waitingForInteraction = false;
        if (sm_smActive) { // not cancelled
            sm_interactionActive = true;
            qt_sm_blockUserInput = false;
            return true;
        }
    }
    return false;
}

void QXcbSessionManager::release()
{
    if (sm_interactionActive) {
        SmcInteractDone(smcConnection, False);
        sm_interactionActive = false;
        if (sm_smActive && sm_isshutdown)
            qt_sm_blockUserInput = true;
    }
}

void QXcbSessionManager::cancel()
{
    sm_cancel = true;
}

void QXcbSessionManager::setManagerProperty(const QString &name, const QString &value)
{
    sm_setProperty(name, value);
}

void QXcbSessionManager::setManagerProperty(const QString &name, const QStringList &value)
{
    sm_setProperty(name, value);
}

bool QXcbSessionManager::isPhase2() const
{
    return sm_in_phase2;
}

void QXcbSessionManager::requestPhase2()
{
    sm_phase2 = true;
}

void QXcbSessionManager::exitEventLoop()
{
    m_eventLoop->exit();
}

#include "qxcbsessionmanager.moc"

#endif
