package db

import (
	"fmt"
	"path/filepath"
	"testing"
	"time"
)

func TestWriterBatchCommitDurability(t *testing.T) {
	dir := t.TempDir()
	dbPath := filepath.Join(dir, "test.sqlite")
	conn, err := Open(dbPath)
	if err != nil {
		t.Fatal(err)
	}
	if err := EnsureSchema(conn); err != nil {
		t.Fatal(err)
	}
	if _, err := conn.Exec("INSERT INTO posts (keyword, slug, status) VALUES ('k1','k1',0), ('k2','k2',0), ('k3','k3',0)"); err != nil {
		t.Fatal(err)
	}

	w := NewWriter(conn, WriterOptions{BatchSize: 2, FlushEvery: 50 * time.Millisecond})
	for i := 1; i <= 3; i++ {
		UpdateImages(nil, w, int64(i), fmt.Sprintf(`[{"title":"t%d","image_url":"u%d"}]`, i, i))
	}
	w.Close()

	var filled int
	if err := conn.QueryRow(`SELECT COUNT(*) FROM posts WHERE images IS NOT NULL AND status = 1`).Scan(&filled); err != nil {
		t.Fatal(err)
	}
	if filled != 3 {
		t.Fatalf("want 3 updated rows after close flush, got %d", filled)
	}
	conn.Close()
}

func TestWriterFlushOnClose(t *testing.T) {
	dir := t.TempDir()
	dbPath := filepath.Join(dir, "test2.sqlite")
	conn, err := Open(dbPath)
	if err != nil {
		t.Fatal(err)
	}
	if err := EnsureSchema(conn); err != nil {
		t.Fatal(err)
	}
	if _, err := conn.Exec("INSERT INTO posts (keyword, slug, status) VALUES ('k1','k1',0)"); err != nil {
		t.Fatal(err)
	}

	w := NewWriter(conn, WriterOptions{BatchSize: 1000, FlushEvery: time.Hour})
	UpdateAITitle(w, 1, "My Title")
	w.Close()

	var title string
	if err := conn.QueryRow(`SELECT ai_title FROM posts WHERE id = 1`).Scan(&title); err != nil {
		t.Fatal(err)
	}
	if title != "My Title" {
		t.Fatalf("want flush on close, got %q", title)
	}
	updates, batches := w.Stats()
	if updates != 1 || batches != 1 {
		t.Fatalf("stats = %d/%d", updates, batches)
	}
	conn.Close()
}
