#!/usr/bin/env python3

"""qbth - qbittorrent helper

Usage:
    qbth (HOSTNAME) (USERNAME) (PASSWORD)
    qbth -h

Examples:
    qbth "http://localhost:8080" "admin" "adminadmin"
    qbth "https://cat.seedhost.eu/lol/qbittorrent" "lol" "meow"

Options:
    -h, --help      show this help message and exit
"""

import json
import os
import subprocess

import requests
from bs4 import BeautifulSoup
from docopt import docopt
from qbittorrent import Client

args = docopt(__doc__)
qb = Client(args["HOSTNAME"])
qb.login(username=args["USERNAME"], password=args["PASSWORD"])


def add_torrents(urls: list[str]):
    for url in urls:
        qb.download_from_link(url, category="distro")
        print(f"Added {os.path.basename(url)}")


def add_torrents_from_html(webpage_url: str, torrent_substring: str):
    reqs = requests.get(webpage_url, timeout=60)
    soup = BeautifulSoup(reqs.text, "html.parser")
    for link in soup.find_all("a"):
        if torrent_substring in link.get("href"):
            url = f"{webpage_url}/{link.get('href')}"
            qb.download_from_link(url, category="distro")
            print(f"Added {link.get('href')}")


def remove_torrents(distro_substring: str):
    torrents = qb.torrents()
    for torrent in torrents:
        if distro_substring in torrent["name"]:
            qb.delete_permanently(torrent["hash"])
            print(f"Removed {torrent['name']}")


def add_almalinux(relver: str):
    urls = [
        f"https://almalinux-mirror.dal1.hivelocity.net/{relver}/isos/aarch64/AlmaLinux-{relver}-aarch64.torrent",
        f"https://almalinux-mirror.dal1.hivelocity.net/{relver}/isos/ppc64le/AlmaLinux-{relver}-ppc64le.torrent",
        f"https://almalinux-mirror.dal1.hivelocity.net/{relver}/isos/s390x/AlmaLinux-{relver}-s390x.torrent",
        f"https://almalinux-mirror.dal1.hivelocity.net/{relver}/isos/x86_64/AlmaLinux-{relver}-x86_64.torrent",
    ]

    add_torrents(urls)


def remove_almalinux(relver: str):
    remove_torrents(f"AlmaLinux-{relver}")


def add_debian(relver: str):
    urls = [
        f"https://cdimage.debian.org/debian-cd/current/amd64/bt-dvd/debian-{relver}-amd64-DVD-1.iso.torrent",
        f"https://cdimage.debian.org/debian-cd/current/arm64/bt-dvd/debian-{relver}-arm64-DVD-1.iso.torrent",
        f"https://cdimage.debian.org/debian-cd/current/armel/bt-dvd/debian-{relver}-armel-DVD-1.iso.torrent",
        f"https://cdimage.debian.org/debian-cd/current/armhf/bt-dvd/debian-{relver}-armhf-DVD-1.iso.torrent",
        f"https://cdimage.debian.org/debian-cd/current/mips64el/bt-dvd/debian-{relver}-mips64el-DVD-1.iso.torrent",
        f"https://cdimage.debian.org/debian-cd/current/mipsel/bt-dvd/debian-{relver}-mipsel-DVD-1.iso.torrent",
        f"https://cdimage.debian.org/debian-cd/current/ppc64el/bt-dvd/debian-{relver}-ppc64el-DVD-1.iso.torrent",
        f"https://cdimage.debian.org/debian-cd/current/s390x/bt-dvd/debian-{relver}-s390x-DVD-1.iso.torrent",
    ]

    add_torrents(urls)


def remove_debian(relver: str):
    remove_torrents(f"debian-{relver}")


def add_devuan(relver: str):
    url = f"https://files.devuan.org/devuan_{relver}.torrent"
    qb.download_from_link(url, category="distro")
    print(f"Added {os.path.basename(url)}")


def remove_devuan(relver: str):
    remove_torrents(f"devuan_{relver}")


def add_fedora(relver: str):
    webpage_url = "https://torrent.fedoraproject.org/torrents"
    torrent_substring = f"{relver}.torrent"
    add_torrents_from_html(webpage_url, torrent_substring)


def remove_fedora(relver: str):
    torrents = qb.torrents()
    for torrent in torrents:
        if torrent["name"].startswith("Fedora") and torrent["name"].endswith(relver):
            qb.delete_permanently(torrent["hash"])
            print(f"Removed {torrent['name']}")


def add_freebsd(relver: str):
    url = f"https://people.freebsd.org/~jmg/FreeBSD-{relver}-R-magnet.txt"
    reqs = requests.get(url, timeout=60)
    data = reqs.text.split("\n")

    for line in data:
        if line.startswith("magnet:"):
            qb.download_from_link(line, category="distro")
            print(f"Added {line.split('=')[2]}")


def remove_freebsd(relver: str):
    remove_torrents(f"FreeBSD-{relver}")


def add_kali():
    webpage_url = "https://kali.download/base-images/current"
    torrent_substring = ".torrent"
    add_torrents_from_html(webpage_url, torrent_substring)


def remove_kali():
    remove_torrents(f"kali-linux")


def add_netbsd(relver: str):
    webpage_url = f"https://cdn.netbsd.org/pub/NetBSD/NetBSD-{relver}/images/"
    torrent_substring = f".torrent"
    add_torrents_from_html(webpage_url, torrent_substring)


def remove_netbsd(relver: str):
    remove_torrents(f"NetBSD-{relver}")


def add_nixos():
    url = "https://api.github.com/repos/AnimMouse/NixOS-ISO-Torrents/releases/latest"
    reqs = requests.get(url, timeout=60)
    json_data = json.loads(reqs.text)
    for item in json_data["assets"]:
        qb.download_from_link(item["browser_download_url"], category="distro")
        print(f"Added {os.path.basename(item['browser_download_url'])}")


def remove_nixos():
    remove_torrents("nixos")


def add_qubes(relver: str):
    url = f"https://mirrors.edge.kernel.org/qubes/iso/Qubes-R{relver}-x86_64.torrent"
    qb.download_from_link(url, category="distro")
    print(f"Added {os.path.basename(url)}")


def remove_qubes(relver: str):
    remove_torrents(f"Qubes-R{relver}")


def add_rockylinux(relver: str):
    urls = [
        f"https://download.rockylinux.org/pub/rocky/{relver}/isos/aarch64/Rocky-{relver}-aarch64-dvd.torrent",
        f"https://download.rockylinux.org/pub/rocky/{relver}/isos/ppc64le/Rocky-{relver}-ppc64le-dvd.torrent",
        f"https://download.rockylinux.org/pub/rocky/{relver}/isos/s390x/Rocky-{relver}-s390x-dvd.torrent",
        f"https://download.rockylinux.org/pub/rocky/{relver}/isos/x86_64/Rocky-{relver}-x86_64-dvd.torrent",
    ]

    add_torrents(urls)


def remove_rockylinux(relver: str):
    remove_torrents(f"Rocky-{relver}")


def add_tails(relver: str):
    urls = [
        f"https://tails.net/torrents/files/tails-amd64-{relver}.img.torrent",
        f"https://tails.net/torrents/files/tails-amd64-{relver}.iso.torrent",
    ]

    add_torrents(urls)


def remove_tails(relver: str):
    remove_torrents(f"tails-amd64-{relver}")


if __name__ == "__main__":
    distro_selection = subprocess.run(
        [
            "gum",
            "choose",
            "--limit=1",
            "--header='Available torrents'",
            "--height=13",
            "AlmaLinux",
            "Debian",
            "Devuan",
            "Fedora",
            "FreeBSD",
            "Kali Linux",
            "NetBSD",
            "NixOS",
            "Qubes",
            "Rocky Linux",
            "Tails",
        ],
        stdout=subprocess.PIPE,
        text=True,
    ).stdout.strip()

    action_selection = subprocess.run(
        ["gum", "choose", "--limit=1", "--header='Choose:'", "Add", "Remove"],
        stdout=subprocess.PIPE,
        text=True,
    ).stdout.strip()

    relver = subprocess.run(
        ["gum", "input", f"--placeholder='Enter {distro_selection} release version'"],
        stdout=subprocess.PIPE,
        text=True,
    ).stdout.strip()

    match distro_selection:
        case "AlmaLinux":
            if action_selection == "Add":
                add_almalinux(relver)

            if action_selection == "Remove":
                remove_almalinux(relver)

        case "Debian":
            if action_selection == "Add":
                add_debian(relver)

            if action_selection == "Remove":
                remove_debian(relver)

        case "Devuan":
            if action_selection == "Add":
                add_devuan(relver)

            if action_selection == "Remove":
                remove_devuan(relver)

        case "Fedora":
            if action_selection == "Add":
                add_fedora(relver)

            if action_selection == "Remove":
                remove_fedora(relver)

        case "FreeBSD":
            if action_selection == "Add":
                add_freebsd(relver)

            if action_selection == "Remove":
                remove_freebsd(relver)

        case "Kali Linux":
            if action_selection == "Add":
                add_kali()

            if action_selection == "Remove":
                remove_kali()

        case "NetBSD":
            if action_selection == "Add":
                add_netbsd(relver)

            if action_selection == "Remove":
                remove_netbsd(relver)

        case "NixOS":
            if action_selection == "Add":
                add_nixos()

            if action_selection == "Remove":
                remove_nixos()

        case "Qubes":
            if action_selection == "Add":
                add_qubes(relver)

            if action_selection == "Remove":
                remove_qubes(relver)

        case "Rocky Linux":
            if action_selection == "Add":
                add_rockylinux(relver)

            if action_selection == "Remove":
                remove_rockylinux(relver)

        case "Tails":
            if action_selection == "Add":
                add_tails(relver)

            if action_selection == "Remove":
                remove_tails(relver)

        case _:
            print("Nothing to do.")