/**
 * Copyright (c) 2022
 *    Marcus Britanicus (https://gitlab.com/marcusbritanicus)
 *    Abrar (https://gitlab.com/s96Abrar)
 *    rahmanshaber (https://gitlab.com/rahmanshaber)
 *
 * IMPL Class
 *  The UPowerBackend watches the org.freedesktop.UPower and
 *  relays the relevent information to DFL::PowerManager class.
 *  This is purely an implementational detail.
 *  This class can be modified/removed at anytime.
 **/

#pragma once

#include <QtCore>

namespace DFL {
    class Login1;
}

struct login1_impl_t;
typedef struct login1_impl_t Login1Impl;

class DFL::Login1 : public QObject {
    Q_OBJECT;

    public:
        enum InhibitorLock {
            SleepLock        = 1 << 0,
            ShutdownLock     = 1 << 1,
            IdleLock         = 1 << 2,
            PowerKeyLock     = 1 << 3,
            SuspendKeyLock   = 1 << 4,
            HibernateKeyLock = 1 << 5,
            LidSwitchLock    = 1 << 6,
        };
        Q_DECLARE_FLAGS( InhibitorLocks, InhibitorLock );

        Login1( QObject *parent = nullptr );
        ~Login1();

        /** Acquire/Release inhibitor locks */
        void acquireInhibitLocks( DFL::Login1::InhibitorLocks locks );
        void releaseInhibitLocks();

        /** Set the brightness of all the displays */
        bool setBrightness( qreal value );

        /** Set the brightness of the given display */
        bool setBrightness( QString, QString, uint );

        /**
         * Handle various requests.
         * These requests are meant to come from the DE that's using this lib.
         * An action request on this channel will simply release the suitable lock,
         * and perform the action, without intimating the user.
         *
         * Following action requests are allowed:
         *  - [Can]Suspend
         *  - [Can]SuspendThenHibernate
         *  - [Can]Hibernate
         *  - [Can]HybridSleep
         *  - [Can]PowerOff
         *  - [Can]Reboot
         *  - [Un]LockSession
         * All the Can* queries return -2/-1/0/1, representing NA, Challenge, No, and Yes.
         * All the other requests return 0/1 indicating success or failure.
         * All invalid queries/requests will return 0 indicating a failure.
         */
        Q_SLOT int request( QString );

    private:
        Login1Impl *impl;

        /**
         * PrepareForSleep(...) is called when Suspend/Hibernate is requested. This request
         * is simply ignored by us. We expect the users to use the Power/Logout Menu of the DE.
         * We're interested in waking up from sleep, or if the Sleep request failed to re-acquire
         * the sleep inhibitor lock.
         */
        Q_SLOT void PrepareForSleep( bool active );

        /**
         * PrepareForShutdown(...) is called when PowerOff/Reboot is requested. This request
         * is simply ignored by us. We expect the users to use the Power/Logout Menu of the DE.
         * We're interested in Sleep request failing, so that we can re-acquire the shutdown
         * inhibitor lock.
         */
        Q_SLOT void PrepareForShutdown( bool active );

        /**
         * Lock() is emitted when an external entity has requested that the screen be locked.
         * We can honour this request, by informing the DE about it.
         */
        Q_SLOT void LockSession();

        /**
         * Unlock() is emitted when an external entity has requested that the screen be unlocked.
         * We can honour this request, by informing the DE about it.
         */
        Q_SLOT void UnlockSession();
};

Q_DECLARE_OPERATORS_FOR_FLAGS( DFL::Login1::InhibitorLocks );
