package main

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"slices"
	"strings"
	"testing"
)

func TestHandlerPengguna(t *testing.T) {
	req := httptest.NewRequest(http.MethodGet, "/pengguna", nil)
	rec := httptest.NewRecorder()
	HandlerPengguna(rec, req)

	if rec.Code != http.StatusOK {
		t.Fatalf("status = %d; want %d", rec.Code, http.StatusOK)
	}
	if got := rec.Header().Get("Content-Type"); got != "application/json" {
		t.Errorf("Content-Type = %q; want %q", got, "application/json")
	}
	var got Pengguna
	if err := json.NewDecoder(rec.Body).Decode(&got); err != nil {
		t.Fatalf("decode body: %v", err)
	}
	want := Pengguna{Nama: "Budi", Email: "budi@example.com"}
	if got != want {
		t.Errorf("got %+v; want %+v", got, want)
	}
}

func TestHandlerPenggunaMethodSalah(t *testing.T) {
	body := strings.NewReader(`{"nama":"Siti"}`)
	req := httptest.NewRequest(http.MethodPost, "/pengguna?detail=penuh", body)
	rec := httptest.NewRecorder()
	HandlerPengguna(rec, req)

	if rec.Code != http.StatusMethodNotAllowed {
		t.Errorf("status = %d; want %d", rec.Code, http.StatusMethodNotAllowed)
	}
}

func TestHandlerCari(t *testing.T) {
	req := httptest.NewRequest(http.MethodGet, "/cari?q=buku", nil)
	rec := httptest.NewRecorder()
	HandlerCari(rec, req)

	if rec.Code != http.StatusOK {
		t.Fatalf("status = %d; want %d", rec.Code, http.StatusOK)
	}
	var got []string
	if err := json.NewDecoder(rec.Body).Decode(&got); err != nil {
		t.Fatalf("decode body: %v", err)
	}
	want := []string{"Buku Tulis", "Buku Gambar"}
	if !slices.Equal(got, want) {
		t.Errorf("got %v; want %v", got, want)
	}
}

func TestHandlerCariTanpaQ(t *testing.T) {
	req := httptest.NewRequest(http.MethodGet, "/cari", nil)
	rec := httptest.NewRecorder()
	HandlerCari(rec, req)

	if rec.Code != http.StatusBadRequest {
		t.Errorf("status = %d; want %d", rec.Code, http.StatusBadRequest)
	}
	if teks := rec.Body.String(); !strings.Contains(teks, "wajib diisi") {
		t.Errorf("body = %q; want pesan parameter q wajib diisi", teks)
	}
}

func TestServerPenuh(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(HandlerPengguna))
	defer server.Close()

	resp, err := http.Get(server.URL + "/pengguna")
	if err != nil {
		t.Fatalf("GET: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		t.Fatalf("status = %d; want %d", resp.StatusCode, http.StatusOK)
	}
	var got Pengguna
	if err := json.NewDecoder(resp.Body).Decode(&got); err != nil {
		t.Fatalf("decode body: %v", err)
	}
	want := Pengguna{Nama: "Budi", Email: "budi@example.com"}
	if got != want {
		t.Errorf("got %+v; want %+v", got, want)
	}
}
