package main

import (
	"os"
	"path/filepath"
	"testing"
)

func TestSimpanMuat(t *testing.T) {
	p := PenyimpananBaru(filepath.Join(t.TempDir(), "tugas.json"))
	asli := tugasContoh()

	if err := p.Simpan(asli); err != nil {
		t.Fatalf("Simpan error tak terduga: %v", err)
	}

	dimuat, err := p.Muat()
	if err != nil {
		t.Fatalf("Muat error tak terduga: %v", err)
	}
	if len(dimuat) != len(asli) {
		t.Fatalf("Muat mengembalikan %d tugas; want %d", len(dimuat), len(asli))
	}
	for i := range asli {
		if !dimuat[i].Equal(asli[i]) {
			t.Errorf("tugas ke-%d berbeda setelah muat: got %+v; want %+v", i, dimuat[i], asli[i])
		}
	}
}

func TestMuatBerkasBelumAda(t *testing.T) {
	p := PenyimpananBaru(filepath.Join(t.TempDir(), "belum-ada.json"))

	tasks, err := p.Muat()
	if err != nil {
		t.Fatalf("Muat pada berkas yang belum ada error: %v", err)
	}
	if len(tasks) != 0 {
		t.Errorf("Muat mengembalikan %d tugas; want 0", len(tasks))
	}
}

func TestMuatJSONRusak(t *testing.T) {
	berkas := filepath.Join(t.TempDir(), "rusak.json")
	if err := os.WriteFile(berkas, []byte("bukan json"), 0o600); err != nil {
		t.Fatalf("menulis berkas uji: %v", err)
	}

	p := PenyimpananBaru(berkas)
	if _, err := p.Muat(); err == nil {
		t.Fatal("Muat pada JSON rusak harus error, tetapi berhasil")
	}
}

func TestSimpanIsiBerkas(t *testing.T) {
	direktori := t.TempDir()
	p := PenyimpananBaru(filepath.Join(direktori, "tugas.json"))

	if err := p.Simpan([]Task{{ID: 1, Judul: "Belajar Go", Dibuat: waktuBeku}}); err != nil {
		t.Fatalf("Simpan error tak terduga: %v", err)
	}

	data, err := os.ReadFile(filepath.Join(direktori, "tugas.json"))
	if err != nil {
		t.Fatalf("membaca berkas hasil Simpan: %v", err)
	}

	want := `[
  {
    "id": 1,
    "judul": "Belajar Go",
    "selesai": false,
    "dibuat": "2026-01-15T08:00:00Z"
  }
]
`
	if string(data) != want {
		t.Errorf("isi berkas = %q; want %q", data, want)
	}

	sisa, err := filepath.Glob(filepath.Join(direktori, "tugas-*.tmp"))
	if err != nil {
		t.Fatalf("Glob error tak terduga: %v", err)
	}
	if len(sisa) != 0 {
		t.Errorf("berkas sementara tertinggal setelah Simpan: %v", sisa)
	}
}

func TestSimpanDaftarKosong(t *testing.T) {
	berkas := filepath.Join(t.TempDir(), "tugas.json")
	p := PenyimpananBaru(berkas)

	if err := p.Simpan(nil); err != nil {
		t.Fatalf("Simpan(nil) error tak terduga: %v", err)
	}

	data, err := os.ReadFile(berkas)
	if err != nil {
		t.Fatalf("membaca berkas hasil Simpan: %v", err)
	}
	if string(data) != "[]\n" {
		t.Errorf("isi berkas = %q; want %q", data, "[]\n")
	}
}

func TestSimpanMenggantiIsi(t *testing.T) {
	p := PenyimpananBaru(filepath.Join(t.TempDir(), "tugas.json"))

	if err := p.Simpan(tugasContoh()); err != nil {
		t.Fatalf("Simpan pertama error: %v", err)
	}
	if err := p.Simpan(nil); err != nil {
		t.Fatalf("Simpan kedua error: %v", err)
	}

	dimuat, err := p.Muat()
	if err != nil {
		t.Fatalf("Muat error tak terduga: %v", err)
	}
	if len(dimuat) != 0 {
		t.Errorf("Muat setelah Simpan kedua mengembalikan %d tugas; want 0", len(dimuat))
	}
}
