"""filetool: CLI pengelola file sederhana."""

import argparse
import sys
from datetime import datetime
from pathlib import Path

VERSI = "1.0.0"


def format_size(ukuran: int) -> str:
    """Ubah ukuran dalam byte menjadi teks yang mudah dibaca manusia."""
    if ukuran < 1024:
        return f"{ukuran} B"
    for satuan in ("KB", "MB", "GB", "TB"):
        ukuran /= 1024
        if ukuran < 1024:
            return f"{ukuran:.1f} {satuan}".replace(".", ",")
    return f"{ukuran:.1f} PB".replace(".", ",")


def format_waktu(epoch: float) -> str:
    """Ubah stempel waktu epoch menjadi teks tanggal dan jam."""
    return datetime.fromtimestamp(epoch).strftime("%Y-%m-%d %H:%M")


def perintah_daftar(args: argparse.Namespace) -> int:
    direktori = Path(args.path)
    if not direktori.is_dir():
        print(f"filetool: bukan direktori: {direktori}", file=sys.stderr)
        return 1
    for entri in sorted(direktori.iterdir()):
        penanda = "d" if entri.is_dir() else "-"
        if args.panjang:
            stat = entri.stat()
            ukuran = "-" if entri.is_dir() else format_size(stat.st_size)
            print(f"{penanda} {ukuran:>8}  {format_waktu(stat.st_mtime)}  {entri.name}")
        else:
            akhiran = "/" if entri.is_dir() else ""
            print(f"{entri.name}{akhiran}")
    return 0


def perintah_info(args: argparse.Namespace) -> int:
    berkas = Path(args.path)
    if not berkas.is_file():
        print(f"filetool: bukan berkas: {berkas}", file=sys.stderr)
        return 1
    stat = berkas.stat()
    for label, nilai in [
        ("jalur", str(berkas)),
        ("jenis", "berkas"),
        ("ekstensi", berkas.suffix or "(tidak ada)"),
        ("ukuran", f"{stat.st_size} byte ({format_size(stat.st_size)})"),
        ("diubah", format_waktu(stat.st_mtime)),
    ]:
        print(f"{label:<9}: {nilai}")
    return 0


def perintah_cari(args: argparse.Namespace) -> int:
    akar = Path(args.path)
    if not akar.is_dir():
        print(f"filetool: bukan direktori: {akar}", file=sys.stderr)
        return 1
    hasil = sorted(p for p in akar.rglob(args.pola) if p.is_file())
    if not hasil:
        print("tidak ada yang cocok.")
        return 0
    for jalur in hasil:
        print(jalur.relative_to(akar))
    return 0


def buat_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="filetool",
        description="Pengelola file dari terminal.",
    )
    parser.add_argument("--versi", action="version", version=f"filetool {VERSI}")
    sub = parser.add_subparsers(dest="perintah", required=True, metavar="PERINTAH")

    p_daftar = sub.add_parser("daftar", help="tampilkan isi sebuah direktori")
    p_daftar.add_argument("path", help="direktori yang ingin ditampilkan")
    p_daftar.add_argument("--panjang", action="store_true",
                          help="tampilkan ukuran, waktu ubah, dan nama")
    p_daftar.set_defaults(func=perintah_daftar)

    p_info = sub.add_parser("info", help="tampilkan metadata sebuah berkas")
    p_info.add_argument("path", help="berkas yang ingin diperiksa")
    p_info.set_defaults(func=perintah_info)

    p_cari = sub.add_parser("cari", help="cari berkas berdasarkan pola glob")
    p_cari.add_argument("path", help="direktori awal pencarian")
    p_cari.add_argument("--pola", default="*", help='pola nama berkas, misalnya "*.txt"')
    p_cari.set_defaults(func=perintah_cari)

    return parser


def main(argv: list[str] | None = None) -> int:
    args = buat_parser().parse_args(argv)
    return args.func(args)


if __name__ == "__main__":
    sys.exit(main())
