#!/usr/bin/env python3
# femctl - a simplle sysv cli bootscript manager
# Copyright (C) 2025 Gabriel Di Martino
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
import os
import sys
import subprocess
import tarfile
import urllib.request
import difflib
from pathlib import Path
import re

"""This is a small utility frontend for blfs bootscripts, the bootscripts remain to the BLFS Authors"""

BOOTSCRIPT_VER = "20250225"
BLFS_URL = f"https://anduin.linuxfromscratch.org/BLFS/blfs-bootscripts/blfs-bootscripts-{BOOTSCRIPT_VER}.tar.xz"
CACHE_DIR = Path.home() / ".blfs_cache"
TARBALL = CACHE_DIR / "blfs-bootscripts.tar.xz"
SRC_DIR = CACHE_DIR / f"blfs-bootscripts-{BOOTSCRIPT_VER}"

def check_root():
    if os.geteuid() != 0:
        print("This script must be run as root!")
        sys.exit(1)

def download_tarball():
    CACHE_DIR.mkdir(parents=True, exist_ok=True)
    if not TARBALL.exists():
        print(f"Downloading BLFS bootscripts to {TARBALL}...")
        urllib.request.urlretrieve(BLFS_URL, TARBALL)
    else:
        print(f"Using cached tarball at {TARBALL}")

def extract_tarball():
    if not SRC_DIR.exists():
        print(f"Extracting tarball to {SRC_DIR}...")
        SRC_DIR.mkdir(parents=True)
        with tarfile.open(TARBALL, "r:xz") as tar:
            tar.extractall(path=CACHE_DIR)
    else:
        print(f"Using cached source at {SRC_DIR}")

def parse_services():
    makefile_path = SRC_DIR / "Makefile"
    if not makefile_path.exists():
        print(f"Makefile not found in {SRC_DIR}, did extraction fail?")
        sys.exit(1)

    services = set()
    with open(makefile_path) as f:
        content = f.read()
        # Find install- and uninstall- targets
        for match in re.findall(r'(?:install|uninstall)-([a-zA-Z0-9_-]+)', content):
            services.add(match)
    return sorted(services)

def suggest_service(name, services):
    matches = difflib.get_close_matches(name, services, n=1)
    if matches:
        print(f"{name} does not exist. Did you mean {matches[0]}?")
    else:
        print(f"{name} does not exist and no close match was found.")

def run_make(service, action, services):
    if service not in services:
        suggest_service(service, services)
        return
    target = f"{action}-{service}"
    print(f"Running `make {target}`...")
    subprocess.run(["make", target], cwd=SRC_DIR, check=True)

def print_version():
    print("""Femctl version 1.0.1

Made by gabry for FemboyOS
Credits to the BLFS authors for the BLFS bootscripts""")

def print_help():
    print("""Usage: femctl <command> <service>
Commands:
  enable   Enable a service (make install-{service})
  disable  Disable a service (make uninstall-{service})
  version  Shows version and credits
  help     Show this message

Example:
  femctl enable sshd
  femctl disable sshd""")

def main():
    check_root()
    if len(sys.argv) < 2 or sys.argv[1] in ("help", "-h", "--help"):
        print_help()
        return
    elif len(sys.argv) <2 or sys.argv[1] in ("version"):
        print_version()
        return

    download_tarball()
    extract_tarball()
    services = parse_services()

    command = sys.argv[1]
    if len(sys.argv) < 3:
        print("Please specify a service name.")
        return
    service = sys.argv[2]

    if command == "enable":
        run_make(service, "install", services)
    elif command == "disable":
        run_make(service, "uninstall", services)
    else:
        print_help()

if __name__ == "__main__":
    main()

