package main

import (
	"errors"
	"testing"
)

func TestMemoryRepository(t *testing.T) {
	tests := []struct {
		nama     string
		jalankan func(t *testing.T)
	}{
		{
			nama: "Create menghasilkan ID berurutan",
			jalankan: func(t *testing.T) {
				repo := NewMemoryRepository()
				pertama, err := repo.Create("Kopi Gayo", 45000)
				if err != nil {
					t.Fatalf("Create pertama gagal: %v", err)
				}
				kedua, err := repo.Create("Teh Melati", 25000)
				if err != nil {
					t.Fatalf("Create kedua gagal: %v", err)
				}
				if pertama.ID != 1 || kedua.ID != 2 {
					t.Errorf("ID = %d, %d; ingin 1, 2", pertama.ID, kedua.ID)
				}
			},
		},
		{
			nama: "Get mengembalikan item yang dibuat",
			jalankan: func(t *testing.T) {
				repo := NewMemoryRepository()
				dibuat, _ := repo.Create("Gula Aren", 15000)
				diambil, err := repo.Get(dibuat.ID)
				if err != nil {
					t.Fatalf("Get gagal: %v", err)
				}
				if diambil != dibuat {
					t.Errorf("Get = %+v; ingin %+v", diambil, dibuat)
				}
			},
		},
		{
			nama: "Get item yang tidak ada mengembalikan ErrNotFound",
			jalankan: func(t *testing.T) {
				repo := NewMemoryRepository()
				_, err := repo.Get(99)
				if !errors.Is(err, ErrNotFound) {
					t.Errorf("err = %v; ingin ErrNotFound", err)
				}
			},
		},
		{
			nama: "List terurut naik berdasarkan ID",
			jalankan: func(t *testing.T) {
				repo := NewMemoryRepository()
				repo.Create("Kopi Gayo", 45000)
				repo.Create("Teh Melati", 25000)
				repo.Create("Gula Aren", 15000)
				daftar, err := repo.List()
				if err != nil {
					t.Fatalf("List gagal: %v", err)
				}
				for i, item := range daftar {
					if item.ID != i+1 {
						t.Errorf("daftar[%d].ID = %d; ingin %d", i, item.ID, i+1)
					}
				}
			},
		},
		{
			nama: "Update item yang tidak ada mengembalikan ErrNotFound",
			jalankan: func(t *testing.T) {
				repo := NewMemoryRepository()
				err := repo.Update(Item{ID: 99, Nama: "Tidak Ada", Harga: 0})
				if !errors.Is(err, ErrNotFound) {
					t.Errorf("err = %v; ingin ErrNotFound", err)
				}
			},
		},
		{
			nama: "Delete menghapus item dari List",
			jalankan: func(t *testing.T) {
				repo := NewMemoryRepository()
				dibuat, _ := repo.Create("Kopi Gayo", 45000)
				if err := repo.Delete(dibuat.ID); err != nil {
					t.Fatalf("Delete gagal: %v", err)
				}
				daftar, _ := repo.List()
				if len(daftar) != 0 {
					t.Errorf("len(List) = %d setelah Delete; ingin 0", len(daftar))
				}
				if _, err := repo.Get(dibuat.ID); !errors.Is(err, ErrNotFound) {
					t.Errorf("Get setelah Delete = %v; ingin ErrNotFound", err)
				}
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.nama, func(t *testing.T) {
			tt.jalankan(t)
		})
	}
}
