package migration

import (
	"bytes"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestFormatLoopDuration(t *testing.T) {
	f := func(t *testing.T, in float64, want string) {
		t.Helper()
		assert.Equal(t, want, formatLoopDuration(in), "formatLoopDuration(%v)", in)
	}
	f(t, 0, "-")
	f(t, -1, "-")
	f(t, 59.9, "59s")
	f(t, 60, "1m")
	f(t, 90, "1m30s")
	f(t, 3599, "59m59s")
	f(t, 3600, "1h")
	f(t, 3660, "1h1m")
	f(t, 86399, "23h59m")
	f(t, 86400, "1d")
	f(t, 86460, "1d1m")
	f(t, 90061, "1d1h1m")
}

func TestFormatBytesOrDash(t *testing.T) {
	assert.Equal(t, "-", formatBytesOrDash(0))
	assert.Equal(t, "-", formatBytesOrDash(-5))
	assert.Equal(t, "1.00K", formatBytesOrDash(1024))
}

func TestFormatRateOrDash(t *testing.T) {
	assert.Equal(t, "-", formatRateOrDash(0))
	assert.Equal(t, "-", formatRateOrDash(-1))
	assert.Equal(t, "2.00K/s", formatRateOrDash(2048))
}

func TestFormatCountStr(t *testing.T) {
	f := func(t *testing.T, done, total int, want string) {
		t.Helper()
		assert.Equal(t, want, formatCountStr(done, total), "formatCountStr(%d, %d)", done, total)
	}
	f(t, 0, 0, "-")
	f(t, 0, 3, "0/3 (no)")
	f(t, 2, 5, "2/5 (no)")
	f(t, 5, 5, "5/5 (yes)")
}

func TestComputeLoopSummaryWidths(t *testing.T) {
	t.Run("HeaderMinimumsWhenNoRows", func(t *testing.T) {
		w := computeLoopSummaryWidths(nil, 5)
		assert.Equal(t, []int{1, 6, 4, 6, 7, 3, 6, 8, 8, 5}, w)
	})

	t.Run("TotalDigitsSetRowColumn", func(t *testing.T) {
		w := computeLoopSummaryWidths(nil, 100000)
		assert.Equal(t, 6, w[0])
	})

	t.Run("CellWiderThanHeaderWidensColumn", func(t *testing.T) {
		rows := []loopSummaryRow{{
			tenant:   "a-very-long-tenant",
			step:     "verify-twice-over",
			status:   StatusCompleted,
			dur:      "1d1h1m",
			shards:   "5/5 (yes)",
			verified: "5/5 (yes)",
			migrated: "1024.00K",
			speed:    "10.00M/s",
		}}
		w := computeLoopSummaryWidths(rows, 3)
		assert.Equal(t, 18, w[1], "tenant column must fit the widest cell")
		assert.Equal(t, len("verify-twice-over"), w[2])
		assert.Equal(t, 9, w[3])
		assert.Equal(t, len("attempt"), w[4], "numeric attempt cells never widen the column")
		assert.Equal(t, 6, w[5])
		assert.Equal(t, 9, w[6])
		assert.Equal(t, 9, w[7])
		assert.Equal(t, 8, w[8])
		assert.Equal(t, 8, w[9])
	})
}

func TestRenderText(t *testing.T) {
	s := &Summary{
		StatusPath:    "/migrations/prod/migration-loop-status.json",
		UpdatedAt:     "2026-08-17T12:00:00Z",
		Total:         2,
		Done:          1,
		Running:       1,
		Percent:       50,
		Complete:      false,
		TotalDuration: 3661,
		TotalMigrated: 2048,
		Rows: []Row{
			{
				Tenant:        "tenants-1",
				Step:          "done",
				Status:        StatusCompleted,
				Attempt:       1,
				Duration:      3661,
				Imported:      2,
				Verified:      2,
				ShardsTotal:   2,
				BytesMigrated: 2048,
			},
			{Tenant: "tenants-2", Step: "migrate", Status: StatusRunning, Attempt: 2, Duration: 30},
		},
	}
	var buf bytes.Buffer
	RenderText(&buf, s)
	out := buf.String()
	for _, want := range []string{
		"migration-loop-status.json  updatedAt=2026-08-17T12:00:00Z",
		"total=2  done=1  running=1  failed=0  pending=0  complete=false  (50% complete)",
		"tenants-1", "completed", "1h1m", "2/2 (yes)", "2.00K",
		"tenants-2", "running", "30s",
		"total time: 1h1m   total migrated: 2.00K",
	} {
		assert.Contains(t, out, want)
	}
}
