package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"
)

func main() {
	// Mux pertama: pola method + path untuk API item (tanpa tangkapan umum).
	api := http.NewServeMux()
	api.HandleFunc("GET /items", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "daftar item")
	})
	api.HandleFunc("POST /items", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusCreated)
		fmt.Fprintln(w, "item dibuat")
	})
	api.HandleFunc("GET /items/{id}", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "detail item: %s\n", r.PathValue("id"))
	})

	fmt.Println("== mux api (pola method + path)")
	uji(api, "GET", "/items")
	uji(api, "GET", "/items/7")
	uji(api, "POST", "/items")
	uji(api, "DELETE", "/items/7")
	uji(api, "GET", "/takada")

	// Mux kedua: akar persis, subtree, dan tangkapan umum.
	situs := http.NewServeMux()
	situs.HandleFunc("GET /{$}", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "halaman utama")
	})
	situs.HandleFunc("GET /static/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "aset statis: %s\n", r.URL.Path)
	})
	situs.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, "halaman tidak ditemukan", http.StatusNotFound)
	})

	fmt.Println("== mux situs (akar persis, subtree, tangkapan umum)")
	uji(situs, "GET", "/")
	uji(situs, "GET", "/static/app.css")
	uji(situs, "GET", "/profil")

	// Pola yang tidak valid memicu panic pada saat registrasi.
	fmt.Println("registrasi pola \"GET\" (tanpa path):")
	func() {
		defer func() { fmt.Println("  panic:", recover()) }()
		m := http.NewServeMux()
		m.HandleFunc("GET", func(w http.ResponseWriter, r *http.Request) {})
	}()
}

func uji(h http.Handler, method, path string) {
	req := httptest.NewRequest(method, path, nil)
	rec := httptest.NewRecorder()
	h.ServeHTTP(rec, req)
	fmt.Printf("%-7s %-15s -> %d | %s\n", method, path, rec.Code,
		strings.TrimSpace(rec.Body.String()))
	if rec.Code == http.StatusMethodNotAllowed {
		fmt.Printf("          Allow: %s\n", rec.Header().Get("Allow"))
	}
}
