package main

import (
	"bytes"
	"fmt"
	"log/slog"
	"strings"
)

// buangWaktu membekukan atribut time pada handler agar output contoh ini
// identik pada setiap eksekusi (timestamp nyata berubah terus).
func buangWaktu() *slog.HandlerOptions {
	return &slog.HandlerOptions{
		Level: slog.LevelInfo,
		ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
			if a.Key == slog.TimeKey && len(groups) == 0 {
				return slog.String(slog.TimeKey, "2026-01-15T08:00:00Z")
			}
			return a
		},
	}
}

// peristiwaRequest memodelkan satu request HTTP yang selesai ditangani.
type peristiwaRequest struct {
	Metode string
	Rute   string
	Status int
	Durasi int // dalam milidetik
}

func main() {
	peristiwa := []peristiwaRequest{
		{"GET", "/api/pesanan", 200, 42},
		{"GET", "/api/pesanan", 500, 1180},
		{"POST", "/api/pesanan", 201, 65},
	}

	fmt.Println("--- gaya lama: log teks bebas ---")
	for _, p := range peristiwa {
		status := "selesai"
		if p.Status >= 500 {
			status = "gagal"
		}
		fmt.Printf("2026-01-15 08:00:00 request %s %s %s status=%d durasi=%dms\n",
			p.Metode, p.Rute, status, p.Status, p.Durasi)
	}

	fmt.Println("--- gaya baru: log terstruktur (JSON) ---")
	var buf bytes.Buffer
	logger := slog.New(slog.NewJSONHandler(&buf, buangWaktu()))
	for _, p := range peristiwa {
		aksi, pesan := logger.Info, "request selesai"
		if p.Status >= 500 {
			aksi, pesan = logger.Error, "request gagal"
		}
		aksi(pesan,
			"metode", p.Metode,
			"rute", p.Rute,
			"status", p.Status,
			"durasi_ms", p.Durasi)
	}

	garis := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n")
	for _, g := range garis {
		fmt.Println(g)
	}

	fmt.Println("--- saringan baris dengan status 500 ---")
	cocok := 0
	for _, g := range garis {
		if strings.Contains(g, `"status":500`) {
			cocok++
			fmt.Println(g)
		}
	}
	fmt.Println("jumlah kecocokan:", cocok)
}
