package uls

import (
	"os"
	"testing"
)

func TestGrid6(t *testing.T) {
	cases := []struct {
		lat, lon float64
		want     string
	}{
		{38.90, -77.03, "FM18lw"},  // Washington DC
		{40.71, -74.00, "FN30xr"},  // New York
		{34.05, -118.24, "DM04vd"}, // Los Angeles
	}
	for _, c := range cases {
		if got := grid6(c.lat, c.lon); got[:4] != c.want[:4] {
			t.Errorf("grid6(%v,%v)=%q want field/square %q", c.lat, c.lon, got, c.want[:4])
		}
	}
}

// TestParseGeoNames runs against the real GeoNames US.zip if present in the
// scratchpad (downloaded during development); skipped otherwise.
func TestParseGeoNames(t *testing.T) {
	path := os.Getenv("GEONAMES_ZIP")
	if path == "" {
		t.Skip("set GEONAMES_ZIP to the US.zip path to run")
	}
	m, err := parseGeoNames(path)
	if err != nil {
		t.Fatal(err)
	}
	if len(m) < 30000 {
		t.Fatalf("expected >30k ZIPs, got %d", len(m))
	}
	// A known ZIP: 20500 = The White House, DC.
	if r, ok := m["20500"]; !ok || r.state != "DC" {
		t.Errorf("ZIP 20500 = %+v (ok=%v)", r, ok)
	}
}

// The real listing captured from data.fcc.gov on 2026-07-25, the day after the
// FCC renamed complete/ to complete.07242026/ and left an empty complete/
// behind — which broke the county-database download for every user.
const fccListing2026 = `<html><head><title>Index of /download/pub/uls</title></head><body>
<h1>Index of /download/pub/uls</h1>
<table><tr><th>Name</th><th>Last modified</th><th>Size</th></tr>
<tr><td><a href="/download/pub/">Parent Directory</a></td><td>&nbsp;</td><td>-</td></tr>
<tr><td><a href="UAT/">UAT/</a></td><td>2025-04-08 19:30</td><td>-</td></tr>
<tr><td><a href="complete.07242026/">complete.07242026/</a></td><td>2026-07-24 20:15</td><td>-</td></tr>
<tr><td><a href="complete/">complete/</a></td><td>2026-07-25 21:15</td><td>-</td></tr>
<tr><td><a href="daily/">daily/</a></td><td>2026-07-25 21:15</td><td>-</td></tr>
</table></body></html>`

func TestParseCompleteDirs(t *testing.T) {
	got := parseCompleteDirs(fccListing2026)
	if len(got) != 1 || got[0] != "complete.07242026/" {
		t.Fatalf("got %v, want [complete.07242026/]", got)
	}
	// "complete/" is deliberately absent: it is the canonical URL, already tried
	// before the listing is consulted, and on this date it was empty.
	for _, d := range got {
		if d == "complete/" {
			t.Error("canonical complete/ should not be offered as a fallback")
		}
	}
}

// Several snapshots must be tried newest-first, so a stale one is never
// preferred over a fresh one.
func TestParseCompleteDirsPrefersNewestSnapshot(t *testing.T) {
	html := `<a href="complete/">x</a><a href="complete.01052026/">x</a>` +
		`<a href="complete.07242026/">x</a><a href="complete.11302025/">x</a>`
	got := parseCompleteDirs(html)
	want := []string{"complete.07242026/", "complete.01052026/", "complete.11302025/"}
	if len(got) != len(want) {
		t.Fatalf("got %v, want %v", got, want)
	}
	for i := range want {
		if got[i] != want[i] {
			t.Fatalf("got %v, want %v", got, want)
		}
	}
}

func TestSnapshotDate(t *testing.T) {
	if d := snapshotDate("complete.07242026/"); d.Format("2006-01-02") != "2026-07-24" {
		t.Errorf("complete.07242026/ → %s, want 2026-07-24", d.Format("2006-01-02"))
	}
	// An undated name must sort last rather than crash.
	if !snapshotDate("complete.backup/").IsZero() {
		t.Error("an undated directory should yield the zero time")
	}
}
