#!/usr/bin/env python3
#
#       Ferit Yiğit BALABAN <fyb@fybx.dev>, 2024
#
#       fetchpy, fetch script alternative to neofetch
#       revision 6
import os
import sys
import subprocess as sp


def print_pipeline(text):
    stage1 = color_text(text)
    stage2 = color_art(stage1, 16)
    print(stage2)
    print('')


def color_art(text, threshold):
    lines = text.splitlines()
    rebuilt = ''
    for line in lines:
        line = '\u001b[33m' + line[:threshold] + '\u001b[0m' + line[threshold:]
        rebuilt += (line + '\n')
    return rebuilt


def color_text(text):
    output = ''
    frame = '\u001b[31m'
    info = '\u001b[32m'
    title = '\u001b[33m'
    clr_dict = {'╭': frame, '╰': frame, '╯': frame, '─': frame, '╮': frame, '│': frame,
                '': info, '': info, '': info, '': info, '': info, '󰢮': info, '': info, '': info,
                'ferit@navi': title,
                'Hardware': ''}
    i = 0
    while i < len(text):
        char = text[i]
        peekable = i < len(text) - 1
        peek = text[i + 1] if peekable else ' '

        if char == ' ':
            if peekable and peek != ' ' and peek not in clr_dict:
                output += ' '
                word, jump_to = read_until_space(text, start_at=i + 1)
                if word in clr_dict:
                    output += f'{clr_dict[word]}{word}\u001b[0m'
                else:
                    output += word
                i = jump_to
            output += ' '
        elif char in clr_dict:
            output += f'{clr_dict[char]}{char}\u001b[0m'
        else:
            output += char
        i += 1
    return output


def read_until_space(text, start_at):
    buffer = ''
    iterator = start_at
    while text[iterator] != ' ':
        buffer += text[iterator]
        iterator += 1
    next_space_at = iterator
    return buffer, next_space_at


def find_username():
    return sp.run(['whoami'], text=True, capture_output=True).stdout[0:-1]


def find_hostname():
    return sp.run(['uname', '-n'], text=True, capture_output=True).stdout[0:-1]


def find_login_shell(username):
    toGrep = sp.Popen(['cat', '/etc/passwd'], stdout=sp.PIPE)
    toSplit = sp.check_output(('grep', f'{username}'), stdin=toGrep.stdout)
    toGrep.wait()
    return toSplit.decode(sys.stdout.encoding)[0:-1].split(':')[-1]


def main():
    props = []
    _username = find_username()
    # _hostname = find_hostname()
    _login_shell = find_login_shell(_username).split('/')[-1]

    props.append('Arch GNU+Linux') # distro_name
    props.append(os.uname().release) #kernel_version

    installed_packages = sp.run(['pacman', '-Q'], text=True, capture_output=True).stdout.splitlines()
    for _ in installed_packages:
        if _login_shell in _:
            props.append(_.removesuffix('\n')) # shell_name
    
    props.append(str(len(installed_packages))) # package_count
    
    total_mem, used_mem, _, _, _, _ = map(int, os.popen('free -m').readlines()[1].split()[1:])
    def rnd(x): return round(x, 1)
    props.append(f'{rnd(used_mem / 1024)} GB / {rnd(total_mem / 1024)} GB') # mem_usage 

    with open('/proc/uptime', 'r', encoding='utf8') as file:
        uptime_seconds = float(file.readline().split()[0])
        file.close()
    
    if uptime_seconds < 60:
        uptime = str(uptime_seconds).split('.', maxsplit=1)[0] + ' seconds'
    elif uptime_seconds < 3600:
        number = str(uptime_seconds / 60).split('.', maxsplit=1)[0]
        uptime = f'{number} minute' if number == '1' else f'{number} minutes'
    else:
        number = str(uptime_seconds / 3600).split('.', maxsplit=1)[0]
        uptime = f'{number} hour' if number == '1' else f'{number} hours'
    props.append(uptime)

    padding_count = 10
    for prop in props:
        if len(prop) > padding_count:
            padding_count = len(prop) + 1
    for i in range(0, len(props)):
        props[i] = props[i].ljust(padding_count, ' ')
    
    txt = \
        f"""       .        ╭───── ferit@navi ─────╮
      / \\       │    {props[0]}│
     /   \\      │    {props[1]}│
    /^.   \\     │    {props[2]}│
   /  .-.  \\    │    {props[3]}│
  /  (   ) _\\   │    {props[4]}│
 / _.~   ~._^\\  │    {props[5]}│
/.^         ^.\\ ╰──────────────────────╯
"""

    print_pipeline(txt)


if __name__ == '__main__':
    main()
