import os
import dbus 
import subprocess
import sys


class BrowserAgent:

    def __init__(self):

        self.brwoser_list = [
            "/usr/bin/firefox",
            "/usr/bin/firefox-esr",
            "/usr/bin/google-chrome-stable",
            "/usr/bin/chromium-browser",
            "/usr/bin/lbrowser",
            "/usr/bin/browser360-cn-stable",
            "/usr/bin/qaxbrowser-safe-stable"
        ]

        self.xdg_list = [
            "/usr/bin/xdg-open",
            "/usr/bin/gvfs-open",
            "/usr/bin/gio",
        ]

    def update_browser(self):
        for browser in self.brwoser_list:
            if not os.path.exists(browser):
                os.system("ln -sf /usr/bin/hostAgent {}".format(browser))

    def update_xdg(self):
        for xdg in self.xdg_list:
            os.system("ln -sf /usr/bin/hostAgent {}".format(xdg))
        os.system("ln -sf /usr/bin/python2 /usr/bin/python")
        os.system("echo '#!/bin/bash' > /usr/bin/kylin-installer")
        os.system("echo 'cd /' >> /usr/bin/kylin-installer")
        os.system("echo 'host-spawn kylin-installer \"$@\"' >> /usr/bin/kylin-installer")
        os.system("chmod +x /usr/bin/kylin-installer")
        


class HostAgent:

    def __init__(self):
        self.common_list = [
            "who",
            "users"
        ]
        self.TMP_FILE = "/tmp/containerInit.tmp"
        self.DBUS_SETTINGS = {
            "dest": "com.kylin.kare.Sessionhost",
            "path": "/com/kylin/kare/Sessionhost",
            "interface": "com.kylin.kare.Sessionhost",
            "method": "call"
        }
        self.uid = self.get_user_by_login1()
        if self.uid is None:
            self.uid = 1000
        self.bus_address = "unix:path=/run/user/{}/bus".format(self.uid)
    def get_user_by_login1(self):
        try:
            # 获取系统总线
            bus = dbus.SystemBus()
            
            # 获取 login1 管理接口
            login1_proxy = bus.get_object(
                "org.freedesktop.login1",
                "/org/freedesktop/login1"
            )
            manager_iface = dbus.Interface(
                login1_proxy,
                "org.freedesktop.login1.Manager"
            )
            
            # 调用 ListUsers 方法
            users = manager_iface.ListUsers()
            
            # 遍历用户
            for user in users:
                # user 结构为 (uid, username, object_path)
                user_path = user[2]
                user_proxy = bus.get_object("org.freedesktop.login1", user_path)
                
                # 获取用户属性接口
                user_iface = dbus.Interface(
                    user_proxy,
                    dbus_interface=dbus.PROPERTIES_IFACE
                )
                
                # 读取 State 属性
                state = user_iface.Get(
                    "org.freedesktop.login1.User",
                    "State"
                )
                
                if state == "active":
                    return user[0]
            
            return None
        except dbus.exceptions.DBusException as e:
            return None
        except Exception as e:
            return None
    

    def get_dbus_response(self, command):
        """通过DBus获取命令响应"""
        try:
            # 连接会话总线
            bus = dbus.SessionBus()
            proxy = bus.get_object(self.DBUS_SETTINGS["dest"], self.DBUS_SETTINGS["path"])
            interface = dbus.Interface(proxy, self.DBUS_SETTINGS["interface"])
            
            # 调用方法并获取响应
            response = interface.call(command)
            return str(response) if response else ""
        
        except dbus.exceptions.DBusException as e:
            print(f"DBus调用失败: {e}")
            return ""

    def create_executable_script(self, cmd):
        value = r"""
import dbus
import os

def main():
    try:
        os.seteuid({})
        bus_connect = dbus.bus.BusConnection("{}")
        proxy = bus_connect.get_object("com.kylin.kare.Sessionhost", "/com/kylin/kare/Sessionhost")
        interface = dbus.Interface(proxy, "com.kylin.kare.Sessionhost")
        response = interface.call("{}")
        print(response)
    
    except dbus.exceptions.DBusException as e:
        print("")

if __name__ == "__main__":
    main()
""".format(self.uid, self.bus_address, cmd)

        """创建带sudo权限的可执行脚本"""
        try:
            # 生成目标路径
            efile = f"/usr/bin/{cmd}-kare"
            
            # 通过sudo创建文件
            subprocess.run(
                ["sudo", "-S", "touch", efile],
                check=True
            )
            
            # 写入内容
            subprocess.run(
                ["sudo", "-S", "tee", efile],
                input=f"#!/usr/bin/python3\n\n{value}\n".encode(),
                check=True,
                stdout=subprocess.DEVNULL
            )
            
            # 设置可执行权限
            subprocess.run(
                ["sudo", "-S", "chmod", "a+x", efile],
                check=True
            )
            # 创建符号链接
            which_path = subprocess.check_output(["which", cmd], text=True).strip()
            subprocess.run(
                ["sudo", "-S", "ln", "-sf", efile, which_path],
                check=True
            )
            
        except subprocess.CalledProcessError as e:
            print(f"命令执行失败: {e}")
        except Exception as e:
            print(f"未知错误: {e}")


def create_service_wrapper():
    real_service="/usr/sbin/service.real"
    service_path="/usr/sbin/service"
    if os.path.exists(real_service):
        return  
    service_wrapper = r"""#!/bin/bash

export SYSTEMCTL_FORCE_BUS=1 SYSTEMD_IGNORE_CHROOT=1
REAL_SERVICE="/usr/sbin/service.real"

if [ "$1" = "cups" ] && [ "$2" = "restart" ]; then
    SYSTEMCTL_FORCE_BUS=1 SYSTEMD_IGNORE_CHROOT=1 systemctl restart cups.service
    exit 0
fi

exec "$REAL_SERVICE" "$@"

"""
    os.system("mv {} {}".format(service_path, real_service))
    os.system("echo '{}' >> {}".format(service_wrapper, service_path))
    os.system("chmod +x {}".format(service_path))

if __name__ == "__main__":
    package = sys.argv[1]
    host = HostAgent()
    os.environ["DBUS_SESSION_BUS_ADDRESS"] = host.bus_address
    for cmd in host.common_list:
        host.create_executable_script(cmd)

    create_service_wrapper()
    os.system("apt update")
    os.system("apt-file update")
    ret = os.system("/usr/bin/python3 /usr/bin/kare-apt.py {}".format(package))
    if ret != 0:
        print("安装失败")
        exit(-1)
    print("==========Installation succeeded==========")

    b = BrowserAgent()
    b.update_browser()
    b.update_xdg()
    package_name = subprocess.getoutput("dpkg -I {} | grep {}".format(package, "Package: ")).split("Package: ")[-1]
    os.system("/usr/bin/python3 /usr/bin/fix_depends.py {}".format(package_name))
    os.system("echo {} > /etc/kare-container".format(package_name))
    os.system('echo "post-invoke /usr/bin/kare-hook.py" > /etc/dpkg/dpkg.cfg.d/kare-hook')
    print("==========Dependencies resolved==========")
