"""Uji otomatis untuk filetool (main.py)."""

import json

import pytest

from main import filter_files, format_size, main, parse_exclude


# --- fungsi murni ---

def test_format_size_dalam_byte():
    assert format_size(0) == "0 B"
    assert format_size(15) == "15 B"
    assert format_size(1023) == "1023 B"


def test_format_size_satuan_besar():
    assert format_size(1536) == "1,5 KB"
    assert format_size(204800) == "200,0 KB"
    assert format_size(1048576) == "1,0 MB"


def test_parse_exclude_dari_string():
    assert parse_exclude(".git, __pycache__,*.tmp ") == [".git", "__pycache__", "*.tmp"]


def test_parse_exclude_kosong_dan_none():
    assert parse_exclude("") == []
    assert parse_exclude(None) == []
    assert parse_exclude([".git", " ", ""]) == [".git"]


def test_filter_files(tmp_path):
    (tmp_path / "buku.txt").touch()
    (tmp_path / "draf.tmp").touch()
    (tmp_path / "simpan.py").touch()
    hasil = filter_files(sorted(tmp_path.iterdir()), ["*.tmp"])
    assert hasil == [tmp_path / "buku.txt", tmp_path / "simpan.py"]


# --- perintah lewat main(argv) ---

@pytest.fixture()
def sandbox(tmp_path, monkeypatch):
    monkeypatch.chdir(tmp_path)
    monkeypatch.delenv("FILETOOL_CONFIG", raising=False)
    (tmp_path / "buku.txt").write_text("isi buku")
    (tmp_path / "draf.tmp").write_text("draf")
    return tmp_path


def test_daftar_menampilkan_isi(sandbox, capsys):
    assert main(["daftar", str(sandbox)]) == 0
    keluar = capsys.readouterr().out
    assert "buku.txt" in keluar
    assert "draf.tmp" in keluar


def test_cari_menghormati_kecuali(sandbox, capsys):
    (sandbox / "lagu.mp3").touch()
    assert main(["cari", str(sandbox), "--pola", "*", "--kecuali", "buku.*"]) == 0
    keluar = capsys.readouterr().out
    assert "lagu.mp3" in keluar
    # buku.txt hilang karena --kecuali; draf.tmp karena pola bawaan "*.tmp"
    assert "buku.txt" not in keluar
    assert "draf.tmp" not in keluar


def test_salin_ke_direktori(sandbox, capsys):
    (sandbox / "folder").mkdir()
    assert main(["salin", "buku.txt", "folder"]) == 0
    assert (sandbox / "folder" / "buku.txt").read_text() == "isi buku"


def test_hapus_tanpa_ya_menolak(sandbox, capsys):
    assert main(["hapus", "buku.txt"]) == 1
    assert "menolak" in capsys.readouterr().out
    assert (sandbox / "buku.txt").exists()


def test_hapus_default_menghapus_permanen(sandbox, capsys):
    assert main(["hapus", "buku.txt", "--ya"]) == 0
    assert not (sandbox / "buku.txt").exists()
    assert not (sandbox / ".filetool-sampah").exists()


def test_hapus_dengan_sampah(sandbox, capsys):
    (sandbox / "config.json").write_text(json.dumps({"gunakan_sampah": True}))
    assert main(["hapus", "buku.txt", "--ya"]) == 0
    assert not (sandbox / "buku.txt").exists()
    assert (sandbox / ".filetool-sampah" / "buku.txt").read_text() == "isi buku"


def test_ukuran_menghormati_kedalaman(sandbox, capsys):
    (sandbox / "config.json").write_text(json.dumps({"kedalaman_rekursif": 1}))
    pohon = sandbox / "pohon"
    (pohon / "dalam").mkdir(parents=True)
    (pohon / "dekat.txt").write_text("x" * 100)
    (pohon / "dalam" / "jauh.txt").write_text("y" * 50)
    assert main(["ukuran", "pohon"]) == 0
    keluar = capsys.readouterr().out
    # hanya dekat.txt (tingkat 1) yang dihitung; jauh.txt ada di tingkat 2
    assert "100 byte" in keluar
    assert "berkas   : 1" in keluar


def test_perintah_tak_dikenal_keluar_2(capsys):
    with pytest.raises(SystemExit) as info:
        main(["bukan-perintah"])
    assert info.value.code == 2
    assert "invalid choice" in capsys.readouterr().err


def test_versi_keluar_0(capsys):
    with pytest.raises(SystemExit) as info:
        main(["--versi"])
    assert info.value.code == 0
    assert "filetool" in capsys.readouterr().out
