package main

import (
	"slices"
	"testing"
	"testing/fstest"
)

// fixtureKatalog menyiapkan seluruh bahan uji: katalog di direktori
// sementara beserta daftar contoh nama produk.
type fixtureKatalog struct {
	katalog *Katalog
	contoh  []string
}

// fixtureKatalogBaru bertindak sebagai setup: direktori sementara
// dibuat lewat t.TempDir dan katalog disiapkan di sana. Pembersihan
// (teardown) direktori berlangsung otomatis saat test selesai.
func fixtureKatalogBaru(t *testing.T) *fixtureKatalog {
	t.Helper()
	k, err := KatalogBaru(t.TempDir())
	if err != nil {
		t.Fatalf("siapkan fixture: %v", err)
	}
	return &fixtureKatalog{
		katalog: k,
		contoh:  []string{"Buku Tulis", "Pensil", "Penghapus"},
	}
}

func TestSimpanMuat(t *testing.T) {
	f := fixtureKatalogBaru(t)
	if err := f.katalog.Simpan("P001", f.contoh); err != nil {
		t.Fatalf("Simpan: %v", err)
	}
	got, err := f.katalog.Muat("P001")
	if err != nil {
		t.Fatalf("Muat: %v", err)
	}
	if !slices.Equal(got, f.contoh) {
		t.Errorf("got %v; want %v", got, f.contoh)
	}
}

func TestDaftarID(t *testing.T) {
	f := fixtureKatalogBaru(t)
	for _, id := range []string{"P002", "P001", "P003"} {
		if err := f.katalog.Simpan(id, f.contoh); err != nil {
			t.Fatalf("Simpan(%s): %v", id, err)
		}
	}
	got, err := f.katalog.DaftarID()
	if err != nil {
		t.Fatalf("DaftarID: %v", err)
	}
	want := []string{"P001", "P002", "P003"}
	if !slices.Equal(got, want) {
		t.Errorf("got %v; want %v", got, want)
	}
}

func TestImpor(t *testing.T) {
	f := fixtureKatalogBaru(t)
	fsys := fstest.MapFS{
		"P001.txt": &fstest.MapFile{Data: []byte("Buku Tulis\nPensil\nPenghapus\n")},
	}
	got, err := f.katalog.Impor(fsys, "P001", "P001.txt")
	if err != nil {
		t.Fatalf("Impor: %v", err)
	}
	if !slices.Equal(got, f.contoh) {
		t.Errorf("got %v; want %v", got, f.contoh)
	}
	disimpan, err := f.katalog.Muat("P001")
	if err != nil {
		t.Fatalf("Muat: %v", err)
	}
	if !slices.Equal(disimpan, f.contoh) {
		t.Errorf("disimpan %v; want %v", disimpan, f.contoh)
	}
}

func TestMuatIDHilang(t *testing.T) {
	f := fixtureKatalogBaru(t)
	_, err := f.katalog.Muat("TIDAK-ADA")
	if err == nil {
		t.Fatal("Muat id hilang: got nil; want error")
	}
}
