package state

import (
	"testing"

	"github.com/bluesky-social/indigo/atproto/syntax"
)

func TestLegacyCursorTID_ConvertsNanos(t *testing.T) {
	nanos := int64(1_700_000_000_123_456_789)
	got, ok := legacyCursorTID("1700000000123456789")
	if !ok {
		t.Fatal("conversion failed for valid nanos")
	}
	parsed, err := syntax.ParseTID(got)
	if err != nil {
		t.Fatalf("not a valid TID: %q err=%v", got, err)
	}
	wantMicros := nanos / 1000
	if parsed.Integer() != uint64(wantMicros)<<10 {
		t.Fatalf("TID encodes micros=%d, want %d", parsed.Integer()>>10, wantMicros)
	}
}

func TestLegacyCursorTID_RejectsNonNumeric(t *testing.T) {
	_, ok := legacyCursorTID("3kmwd6xk6ww22")
	if ok {
		t.Fatal("should reject existing TID-format value")
	}
	_, ok = legacyCursorTID("")
	if ok {
		t.Fatal("should reject empty string")
	}
	_, ok = legacyCursorTID("not-a-number")
	if ok {
		t.Fatal("should reject garbage")
	}
}

func TestLegacyCursorTID_RoundTripsThroughTIDClock(t *testing.T) {
	cases := []int64{
		1_000_000,
		1_700_000_000_000_000_000,
		1_700_000_000_000_001_000,
		1_700_000_000_000_002_000,
	}
	seen := map[string]struct{}{}
	for _, n := range cases {
		got, ok := legacyCursorTID(itoa(n))
		if !ok {
			t.Fatalf("conversion failed for %d", n)
		}
		if _, err := syntax.ParseTID(got); err != nil {
			t.Fatalf("nanos=%d produced non-TID %q: %v", n, got, err)
		}
		if _, dup := seen[got]; dup {
			t.Fatalf("nanos=%d produced duplicate TID %q", n, got)
		}
		seen[got] = struct{}{}
	}
}

func itoa(n int64) string {
	var b [20]byte
	i := len(b)
	neg := n < 0
	if neg {
		n = -n
	}
	if n == 0 {
		return "0"
	}
	for n > 0 {
		i--
		b[i] = byte('0' + n%10)
		n /= 10
	}
	if neg {
		i--
		b[i] = '-'
	}
	return string(b[i:])
}
