#!/usr/bin/env python3

"""
Debugging script
"""

import i3ipc
import os
import psutil

# import alsaaudio
from time import time
import subprocess

i3 = i3ipc.Connection()
lemonbar = subprocess.Popen(["lemonbar", "-b"], stdin=subprocess.PIPE)

# Utils
def upChart(p):
    block = " ▁▂▃▄▅▆▇█"
    return block[round(p * (len(block) - 1))]


def humanSizeOf(num, suffix="B"):  # TODO Credit
    for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]:
        if abs(num) < 1024.0:
            return "%3.0f%2s%s" % (num, unit, suffix)
        num /= 1024.0
    return "%.0f%2s%s" % (num, "Yi", suffix)


# Values
mode = ""
container = i3.get_tree().find_focused()
workspaces = i3.get_workspaces()
outputs = i3.get_outputs()

username = os.environ["USER"]
hostname = os.environ["HOSTNAME"]
if "-" in hostname:
    hostname = hostname.split("-")[-1]

oldNetIO = dict()
oldTime = time()


def update():
    activeOutputs = sorted(
        sorted(list(filter(lambda o: o.active, outputs)), key=lambda o: o.rect.y),
        key=lambda o: o.rect.x,
    )
    z = ""
    for aOutput in range(len(activeOutputs)):
        output = activeOutputs[aOutput]
        # Mode || Workspaces
        t = []
        if mode != "":
            t.append(mode)
        else:
            t.append(
                " ".join(
                    [
                        (w.name.upper() if w.focused else w.name)
                        for w in workspaces
                        if w.output == output.name
                    ]
                )
            )

        # Windows Title
        # if container:
        #    t.append(container.name)

        # CPU
        t.append(
            "C" + "".join([upChart(p / 100) for p in psutil.cpu_percent(percpu=True)])
        )

        # Memory
        t.append(
            "M"
            + str(round(psutil.virtual_memory().percent))
            + "% "
            + "S"
            + str(round(psutil.swap_memory().percent))
            + "%"
        )

        # Disks
        d = []
        for disk in psutil.disk_partitions():
            e = ""
            if disk.device.startswith("/dev/sd"):
                e += "S" + disk.device[-2:].upper()
            elif disk.device.startswith("/dev/mmcblk"):
                e += "M" + disk.device[-3] + disk.device[-1]
            else:
                e += "?"
            e += " "
            e += str(round(psutil.disk_usage(disk.mountpoint).percent)) + "%"
            d.append(e)
        t.append(" ".join(d))

        # Network
        netStats = psutil.net_if_stats()
        netIO = psutil.net_io_counters(pernic=True)
        net = []
        for iface in filter(lambda i: i != "lo" and netStats[i].isup, netStats.keys()):
            s = ""
            if iface.startswith("eth"):
                s += "E"
            elif iface.startswith("wlan"):
                s += "W"
            else:
                s += "?"

            s += " "
            now = time()
            global oldNetIO, oldTime

            sent = (
                (oldNetIO[iface].bytes_sent if iface in oldNetIO else 0)
                - (netIO[iface].bytes_sent if iface in netIO else 0)
            ) / (oldTime - now)
            recv = (
                (oldNetIO[iface].bytes_recv if iface in oldNetIO else 0)
                - (netIO[iface].bytes_recv if iface in netIO else 0)
            ) / (oldTime - now)
            s += (
                "↓"
                + humanSizeOf(abs(recv), "B/s")
                + " ↑"
                + humanSizeOf(abs(sent), "B/s")
            )

            oldNetIO = netIO
            oldTime = now

            net.append(s)
        t.append(" ".join(net))

        # Battery
        if os.path.isdir("/sys/class/power_supply/BAT0"):
            with open("/sys/class/power_supply/BAT0/charge_now") as f:
                charge_now = int(f.read())
            with open("/sys/class/power_supply/BAT0/charge_full_design") as f:
                charge_full = int(f.read())
            t.append("B" + str(round(100 * charge_now / charge_full)) + "%")

        # Volume
        # t.append('V ' + str(alsaaudio.Mixer('Master').getvolume()[0]) + '%')

        t.append(username + "@" + hostname)

        # print(' - '.join(t))
        # t = [output.name]

        z += " - ".join(t) + "%{S" + str(aOutput + 1) + "}"
        # lemonbar.stdin.write(bytes(' - '.join(t), 'utf-8'))
        # lemonbar.stdin.write(bytes('%{S' + str(aOutput + 1) + '}', 'utf-8'))

    lemonbar.stdin.write(bytes(z + "\n", "utf-8"))
    lemonbar.stdin.flush()


# Event listeners
def on_mode(i3, e):
    global mode
    if e.change == "default":
        mode = ""
    else:
        mode = e.change
    update()


i3.on("mode", on_mode)

# def on_window_focus(i3, e):
#    global container
#    container = e.container
#    update()
#
# i3.on("window::focus", on_window_focus)


def on_workspace_focus(i3, e):
    global workspaces
    workspaces = i3.get_workspaces()
    update()


i3.on("workspace::focus", on_workspace_focus)

# Starting

update()


i3.main()