# /*
#  * Copyright (C) 2020, KylinSoft Co., Ltd.
#  *
#  * 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 <https://www.gnu.org/licenses/>.
#  */

import dbus
import psutil
import logging
from defer import Deferred
from SystemUpdater.modules.i18n import _
from SystemUpdater.Core.errors import *
from SystemUpdater.packageManager.pmEnums import *

def PolicyKit_Authority(details = '', sender = None, authentication = False, source=''):
    deferred = Deferred()
    try:        
        #用户鉴权
        logging.info("Authentication via PolicyKit .")
        details = {'polkit.message':details}
        cancel_id = ''

        if False:
            source=source+'-self'

        logging.info('authentication status: %r.',authentication)
        if True == authentication:
            subject = ('system-bus-name', {'name': sender})
            action = get_policykit_authority_action_enum(source)

            def policykit_done(xxx_todo_changeme):
                (authorized, challenged, auth_details) = xxx_todo_changeme
                if authorized:
                    deferred.callback(auth_details)
                elif challenged:
                    deferred.errback(AuthorizationFailed(subject, action))
                else:
                    deferred.errback(NotAuthorizedError(subject, action))

            logging.info("PolicyKit source: %s, action: %s.",source,action)
            kit = dbus.SystemBus().get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority')
            kit = dbus.Interface(kit, 'org.freedesktop.PolicyKit1.Authority')
            kit.CheckAuthorization(subject, action, details, 
                                dbus.UInt32(1), action, 
                                timeout=60*60*24*7,
                                reply_handler=policykit_done,
                                error_handler=deferred.errback)
        else:
            deferred.callback(_("Authentication success."))
    except Exception as e:
        logging.error(e)
        deferred.errback(AuthorizationFailed(subject, action))
    return deferred


class NotAuthorizedError(dbus.DBusException):

    _dbus_error_name = "org.freedesktop.PolicyKit.Error.NotAuthorized"

    def __init__(self, subject, action_id):
        dbus.DBusException.__init__(self, "%s: %s" % (subject, action_id))
        self.action_id = action_id
        self.subject = subject


class AuthorizationFailed(NotAuthorizedError):
    _dbus_error_name = "org.freedesktop.PolicyKit.Error.Failed"


def get_proc_from_dbus_name(dbus_name, bus=None):
    """Return a deferred that gets the id of process owning the given
    system D-Bus name.
    """

    if not bus:
        bus = dbus.SystemBus()
    bus_obj = bus.get_object("org.freedesktop.DBus",
                            "/org/freedesktop/DBus/Bus")
    pid = bus_obj.GetConnectionUnixProcessID(dbus_name,
                                    dbus_interface="org.freedesktop.DBus")
    proc = psutil.Process(int(pid))

    return proc.name()

if __name__ == "__main__":
    pass
