package service

import (
	"context"
	"expvar"
	"fmt"
	"strconv"
	"testing"
	"time"

	"github.com/ez-api/ez-api/internal/model"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

func TestLogWriterMetrics(t *testing.T) {
	dsn := fmt.Sprintf("file:%s?mode=memory&cache=shared", t.Name())
	db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
	if err != nil {
		t.Fatalf("open sqlite: %v", err)
	}
	if err := db.AutoMigrate(&model.LogRecord{}); err != nil {
		t.Fatalf("migrate: %v", err)
	}

	startBatch := getExpvarInt(t, "log_write_batch_total")
	startDropped := getExpvarInt(t, "log_queue_dropped_total")

	dropWriter := NewLogWriter(db, 1, 10, time.Second, nil)
	dropWriter.Write(model.LogRecord{ModelName: "m1", StatusCode: 200})
	dropWriter.Write(model.LogRecord{ModelName: "m2", StatusCode: 200})

	writer := NewLogWriter(db, 10, 1, 10*time.Millisecond, nil)
	ctx, cancel := context.WithCancel(context.Background())
	t.Cleanup(cancel)
	writer.Start(ctx)
	writer.Write(model.LogRecord{ModelName: "m3", StatusCode: 200})

	time.Sleep(50 * time.Millisecond)
	cancel()

	if got := getExpvarInt(t, "log_write_batch_total"); got <= startBatch {
		t.Fatalf("expected batch counter to increase, start=%d got=%d", startBatch, got)
	}
	if got := getExpvarInt(t, "log_queue_dropped_total"); got <= startDropped {
		t.Fatalf("expected dropped counter to be >= start, start=%d got=%d", startDropped, got)
	}
}

func getExpvarInt(t *testing.T, name string) int64 {
	t.Helper()
	v := expvar.Get(name)
	if v == nil {
		t.Fatalf("expvar %s not found", name)
	}
	raw := v.String()
	n, err := strconv.ParseInt(raw, 10, 64)
	if err != nil {
		t.Fatalf("parse expvar %s: %v", name, err)
	}
	return n
}
