#!/usr/bin/python3
import gi
import subprocess

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GLib

def run_command(cmd):
    try:
        subprocess.check_call(cmd, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        return True
    except subprocess.CalledProcessError:
        return False

def check_service_active(service):
    try:
        subprocess.check_call(["systemctl", "is-active", service], 
                             stdout=subprocess.DEVNULL, 
                             stderr=subprocess.DEVNULL)
        return True
    except subprocess.CalledProcessError:
        return False

def check_i2p_active():
    try:
        subprocess.check_call(["i2prouter", "status"], 
                             stdout=subprocess.DEVNULL, 
                             stderr=subprocess.DEVNULL)
        return True
    except (subprocess.CalledProcessError, FileNotFoundError):
        return False

def check_service_enabled(service):
    try:
        subprocess.check_call(["systemctl", "is-enabled", service], 
                             stdout=subprocess.DEVNULL, 
                             stderr=subprocess.DEVNULL)
        return True
    except subprocess.CalledProcessError:
        return False

class AnonUI(Gtk.Window):
    def __init__(self):
        super().__init__(title="AnonUI")
        self.set_default_size(420, 380)
        self.set_resizable(False)
        self.set_border_width(10)
        self.set_icon_from_file("/usr/share/pixmaps/anonui.png")
        self.connect("delete-event", self.on_close)
        self.connect("show", self.on_show)
        self.set_type_hint(Gdk.WindowTypeHint.DIALOG)

        self.tray = Gtk.StatusIcon()
        self.tray.set_from_file("/usr/share/pixmaps/anonui.png")
        self.tray.set_tooltip_text("AnonUI")
        self.tray.set_visible(False)
        self.tray.connect("activate", self.on_tray_left_click)
        self.tray.connect("popup-menu", self.on_tray_right_click)

        main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
        self.add(main_box)

        # Tor section
        frame_tor = Gtk.Frame(label="Tor")
        box_tor = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6, margin=10)
        frame_tor.add(box_tor)

        tor_switch_box = Gtk.Box(spacing=6)
        self.tor_switch = Gtk.Switch(active=check_service_active("tor"))
        self.tor_switch.connect("notify::active", self.on_tor_switch)
        tor_switch_box.pack_start(Gtk.Label(label="Enable Tor:"), False, False, 0)
        tor_switch_box.pack_end(self.tor_switch, False, False, 0)
        box_tor.pack_start(tor_switch_box, False, False, 0)

        btn_box = Gtk.Box(spacing=6)
        btn_restart = Gtk.Button(label="Restart")
        btn_restart.connect("clicked", lambda w: (run_command("pkexec torctl restart"), self.update_ip()))
        btn_newid = Gtk.Button(label="New Identity")
        btn_newid.connect("clicked", lambda w: (run_command("pkexec torctl chngid"), self.update_ip()))
        btn_box.pack_start(btn_restart, True, True, 0)
        btn_box.pack_start(btn_newid, True, True, 0)
        box_tor.pack_start(btn_box, False, False, 0)

        self.chk_autostart = Gtk.CheckButton(label="Autostart", active=check_service_enabled("torctl-autostart.service"))
        self.chk_autostart.connect("toggled", self.on_autostart_toggled)
        box_tor.pack_start(self.chk_autostart, False, False, 0)

        self.chk_autowipe = Gtk.CheckButton(label="Autowipe", active=check_service_enabled("torctl-autowipe.service"))
        self.chk_autowipe.connect("toggled", self.on_autowipe_toggled)
        box_tor.pack_start(self.chk_autowipe, False, False, 0)

        # I2P section
        frame_i2p = Gtk.Frame(label="I2P")
        box_i2p = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6, margin=10)
        frame_i2p.add(box_i2p)

        i2p_switch_box = Gtk.Box(spacing=6)
        self.i2p_switch = Gtk.Switch(active=check_i2p_active())
        self.i2p_switch.connect("notify::active", self.on_i2p_switch)
        i2p_switch_box.pack_start(Gtk.Label(label="Enable I2P:"), False, False, 0)
        i2p_switch_box.pack_end(self.i2p_switch, False, False, 0)
        box_i2p.pack_start(i2p_switch_box, False, False, 0)

        # MAC section
        frame_mac = Gtk.Frame(label="MAC")
        box_mac = Gtk.Box(spacing=6, margin=10)
        frame_mac.add(box_mac)

        btn_mac_change = Gtk.Button(label="Change")
        btn_mac_change.connect("clicked", lambda w: run_command("pkexec torctl chngmac"))
        btn_mac_revert = Gtk.Button(label="Revert")
        btn_mac_revert.connect("clicked", lambda w: run_command("pkexec torctl rvmac"))
        box_mac.pack_start(btn_mac_change, True, True, 0)
        box_mac.pack_start(btn_mac_revert, True, True, 0)

        # IP section
        ip_box = Gtk.Box(spacing=6)
        self.ip_label = Gtk.Label(label="🌐 IP: Not checked")
        btn_ip_refresh = Gtk.Button(label="⟳")
        btn_ip_refresh.connect("clicked", self.update_ip)
        ip_box.pack_start(self.ip_label, True, True, 0)
        ip_box.pack_end(btn_ip_refresh, False, False, 0)

        # Footer
        footer = Gtk.Label(label="AnonUI v7.0 - Privacy Toolkit | B1ack")
        footer.set_margin_top(10)
        footer.set_margin_bottom(5)

        main_box.pack_start(frame_tor, False, False, 0)
        main_box.pack_start(frame_i2p, False, False, 0)
        main_box.pack_start(frame_mac, False, False, 0)
        main_box.pack_start(ip_box, False, False, 0)
        main_box.pack_end(footer, False, False, 0)

        self.update_ip()

    def on_close(self, *args):
        self.hide()
        self.tray.set_visible(True)
        return True

    def on_show(self, *args):
        self.tray.set_visible(False)

    def on_tray_left_click(self, icon):
        self.show_all()
        self.present()
        self.tor_switch.set_active(check_service_active("tor"))
        self.i2p_switch.set_active(check_i2p_active())

    def on_tray_right_click(self, icon, button, time):
        menu = Gtk.Menu()

        tor_item = Gtk.CheckMenuItem(label="Tor", active=check_service_active("tor"))
        tor_item.connect("toggled", self.on_tor_tray_toggled)

        i2p_item = Gtk.CheckMenuItem(label="I2P", active=check_i2p_active())
        i2p_item.connect("toggled", self.on_i2p_tray_toggled)

        quit_item = Gtk.MenuItem(label="Quit")
        quit_item.connect("activate", Gtk.main_quit)

        menu.append(tor_item)
        menu.append(i2p_item)
        menu.append(Gtk.SeparatorMenuItem())
        menu.append(quit_item)

        menu.show_all()
        menu.popup(None, None, Gtk.StatusIcon.position_menu, icon, button, time)

    def on_tor_tray_toggled(self, menuitem):
        new_state = menuitem.get_active()
        cmd = "pkexec torctl start" if new_state else "pkexec torctl stop"
        if run_command(cmd):
            self.tor_switch.set_active(new_state)
        else:
            GLib.idle_add(menuitem.set_active, not new_state)

    def on_i2p_tray_toggled(self, menuitem):
        new_state = menuitem.get_active()
        cmd = "i2prouter start" if new_state else "i2prouter stop"
        if run_command(cmd):
            self.i2p_switch.set_active(new_state)
        else:
            GLib.idle_add(menuitem.set_active, not new_state)

    def on_tor_switch(self, switch, gparam):
        new_state = switch.get_active()
        cmd = "pkexec torctl start" if new_state else "pkexec torctl stop"
        if not run_command(cmd):
            GLib.idle_add(switch.set_active, not new_state)

    def on_i2p_switch(self, switch, gparam):
        new_state = switch.get_active()
        cmd = "i2prouter start" if new_state else "i2prouter stop"
        if not run_command(cmd):
            GLib.idle_add(switch.set_active, not new_state)

    def on_autostart_toggled(self, checkbox):
        action = "enable" if checkbox.get_active() else "disable"
        if not run_command(f"pkexec systemctl {action} torctl-autostart.service"):
            GLib.idle_add(checkbox.set_active, not checkbox.get_active())

    def on_autowipe_toggled(self, checkbox):
        action = "enable" if checkbox.get_active() else "disable"
        if not run_command(f"pkexec systemctl {action} torctl-autowipe.service"):
            GLib.idle_add(checkbox.set_active, not checkbox.get_active())

    def update_ip(self, *args):
        try:
            ip = subprocess.check_output("curl -s https://ipinfo.io/ip", shell=True, text=True).strip()
            self.ip_label.set_text(f"🌐 IP: {ip}")
            self.tray.set_tooltip_text(f"AnonUI - IP: {ip}")
        except subprocess.CalledProcessError:
            self.ip_label.set_text("⚠️ IP: error")
            self.tray.set_tooltip_text("AnonUI - IP error")

if __name__ == "__main__":
    win = AnonUI()
    win.show_all()
    Gtk.main()