package logger

import (
	"os"
	"path/filepath"
	"sync"
	"testing"
	"time"
)

func TestDailyRotatingWriter_DayRotation(t *testing.T) {
	dir := t.TempDir()
	w, err := NewDailyRotatingWriter(dir, "bot1", 50, false)
	if err != nil {
		t.Fatal(err)
	}

	day1 := time.Date(2026, 3, 5, 12, 0, 0, 0, time.UTC)
	day2 := time.Date(2026, 3, 6, 12, 0, 0, 0, time.UTC)

	w.nowFunc = func() time.Time { return day1 }
	// Force re-open with correct day.
	w.current.Close()
	w.currentDay = ""
	w.openFile()

	w.Write([]byte(`{"msg":"day1"}`))

	w.nowFunc = func() time.Time { return day2 }
	w.Write([]byte(`{"msg":"day2"}`))
	w.Close()

	agentDir := filepath.Join(dir, "bot1")
	entries, _ := os.ReadDir(agentDir)

	names := make(map[string]bool)
	for _, e := range entries {
		names[e.Name()] = true
	}

	if !names["2026-03-05.jsonl"] && !names["2026-03-05.jsonl.gz"] {
		t.Error("expected 2026-03-05.jsonl or .gz")
	}
	if !names["2026-03-06.jsonl"] {
		t.Error("expected 2026-03-06.jsonl")
	}
}

func TestDailyRotatingWriter_SizeRotation(t *testing.T) {
	dir := t.TempDir()
	// 1 byte max to force rotation on every write.
	w, err := NewDailyRotatingWriter(dir, "bot2", 0, false)
	if err != nil {
		t.Fatal(err)
	}
	// Override maxSize to a tiny value (can't use 0 MB).
	w.maxSize = 10

	now := time.Date(2026, 3, 6, 10, 0, 0, 0, time.UTC)
	w.nowFunc = func() time.Time { return now }
	w.current.Close()
	w.currentDay = ""
	w.openFile()

	w.Write([]byte(`{"line":1}` + "\n"))
	w.Write([]byte(`{"line":2}` + "\n"))
	w.Write([]byte(`{"line":3}` + "\n"))
	w.Close()

	entries, _ := os.ReadDir(filepath.Join(dir, "bot2"))
	if len(entries) < 2 {
		t.Errorf("expected multiple files from size rotation, got %d", len(entries))
	}
}

func TestDailyRotatingWriter_Concurrent(t *testing.T) {
	dir := t.TempDir()
	w, err := NewDailyRotatingWriter(dir, "bot3", 50, false)
	if err != nil {
		t.Fatal(err)
	}
	defer w.Close()

	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			w.Write([]byte(`{"concurrent":true}` + "\n"))
		}()
	}
	wg.Wait()

	entries, _ := os.ReadDir(filepath.Join(dir, "bot3"))
	if len(entries) == 0 {
		t.Error("expected at least one log file")
	}
}
