-- ============================================================
-- SP-GiST Orbital Trie Benchmark (Phase 3)
-- CelesTrak active catalog, ~14k satellites
-- ============================================================

\timing on

-- ============================================================
-- 1. Catalog distribution analysis
-- ============================================================
SELECT
    CASE
        WHEN tle_perigee(tle) < 2000 THEN 'LEO (<2000km)'
        WHEN tle_perigee(tle) < 20000 THEN 'MEO (2000-20000km)'
        WHEN tle_perigee(tle) < 34000 THEN 'GEO-transfer'
        ELSE 'GEO/HEO (>34000km)'
    END AS regime,
    count(*) AS n,
    round(100.0 * count(*) / (SELECT count(*) FROM bench_catalog), 1) AS pct
FROM bench_catalog
GROUP BY 1
ORDER BY 2 DESC;

-- ============================================================
-- 2. Create indexes
-- ============================================================
\echo '--- CREATE SP-GiST INDEX ---'
CREATE INDEX bench_spgist ON bench_catalog USING spgist (tle tle_spgist_ops);

\echo '--- CREATE GiST INDEX ---'
CREATE INDEX bench_gist ON bench_catalog USING gist (tle tle_ops);

-- Index sizes
SELECT indexname,
       pg_size_pretty(pg_relation_size(indexname::regclass)) AS size
FROM pg_indexes
WHERE tablename = 'bench_catalog'
ORDER BY indexname;

-- ============================================================
-- 3. Benchmark: 2h window, Eagle Idaho (43.7N) — RAAN active
-- ============================================================
\echo '--- BENCHMARK 1: 2h window, Eagle Idaho, 10 deg min_el ---'

-- 3a. Sequential scan (baseline)
SET enable_indexscan = off;
SET enable_bitmapscan = off;
SELECT count(*) AS seqscan_candidates
FROM bench_catalog
WHERE tle &? ROW(
    observer('43.6977N 116.3535W 760m'),
    '2026-02-17 02:00:00+00'::timestamptz,
    '2026-02-17 04:00:00+00'::timestamptz,
    10.0
)::observer_window;
RESET enable_indexscan;
RESET enable_bitmapscan;

-- 3b. SP-GiST index scan
SET enable_seqscan = off;
SELECT count(*) AS spgist_candidates
FROM bench_catalog
WHERE tle &? ROW(
    observer('43.6977N 116.3535W 760m'),
    '2026-02-17 02:00:00+00'::timestamptz,
    '2026-02-17 04:00:00+00'::timestamptz,
    10.0
)::observer_window;
RESET enable_seqscan;

-- ============================================================
-- 4. Benchmark: 24h window, Eagle Idaho — RAAN bypassed
-- ============================================================
\echo '--- BENCHMARK 2: 24h window, Eagle Idaho, 10 deg min_el ---'

SET enable_indexscan = off;
SET enable_bitmapscan = off;
SELECT count(*) AS seqscan_candidates
FROM bench_catalog
WHERE tle &? ROW(
    observer('43.6977N 116.3535W 760m'),
    '2026-02-17 00:00:00+00'::timestamptz,
    '2026-02-18 00:00:00+00'::timestamptz,
    10.0
)::observer_window;
RESET enable_indexscan;
RESET enable_bitmapscan;

SET enable_seqscan = off;
SELECT count(*) AS spgist_candidates
FROM bench_catalog
WHERE tle &? ROW(
    observer('43.6977N 116.3535W 760m'),
    '2026-02-17 00:00:00+00'::timestamptz,
    '2026-02-18 00:00:00+00'::timestamptz,
    10.0
)::observer_window;
RESET enable_seqscan;

-- ============================================================
-- 5. Benchmark: 2h window, Equatorial observer — all inc pass
-- ============================================================
\echo '--- BENCHMARK 3: 2h window, Equator, 10 deg min_el ---'

SET enable_indexscan = off;
SET enable_bitmapscan = off;
SELECT count(*) AS seqscan_candidates
FROM bench_catalog
WHERE tle &? ROW(
    observer('0.0N 0.0E 0m'),
    '2026-02-17 02:00:00+00'::timestamptz,
    '2026-02-17 04:00:00+00'::timestamptz,
    10.0
)::observer_window;
RESET enable_indexscan;
RESET enable_bitmapscan;

SET enable_seqscan = off;
SELECT count(*) AS spgist_candidates
FROM bench_catalog
WHERE tle &? ROW(
    observer('0.0N 0.0E 0m'),
    '2026-02-17 02:00:00+00'::timestamptz,
    '2026-02-17 04:00:00+00'::timestamptz,
    10.0
)::observer_window;
RESET enable_seqscan;

-- ============================================================
-- 6. Benchmark: 45 deg min_el (aggressive altitude filter)
-- ============================================================
\echo '--- BENCHMARK 4: 2h window, Eagle Idaho, 45 deg min_el ---'

SET enable_indexscan = off;
SET enable_bitmapscan = off;
SELECT count(*) AS seqscan_candidates
FROM bench_catalog
WHERE tle &? ROW(
    observer('43.6977N 116.3535W 760m'),
    '2026-02-17 02:00:00+00'::timestamptz,
    '2026-02-17 04:00:00+00'::timestamptz,
    45.0
)::observer_window;
RESET enable_indexscan;
RESET enable_bitmapscan;

SET enable_seqscan = off;
SELECT count(*) AS spgist_candidates
FROM bench_catalog
WHERE tle &? ROW(
    observer('43.6977N 116.3535W 760m'),
    '2026-02-17 02:00:00+00'::timestamptz,
    '2026-02-17 04:00:00+00'::timestamptz,
    45.0
)::observer_window;
RESET enable_seqscan;

-- ============================================================
-- 7. Consistency check: index and seqscan must agree
-- ============================================================
\echo '--- CONSISTENCY CHECK ---'

SET enable_indexscan = off;
SET enable_bitmapscan = off;
CREATE TEMPORARY TABLE seq_results AS
SELECT norad_id FROM bench_catalog
WHERE tle &? ROW(
    observer('43.6977N 116.3535W 760m'),
    '2026-02-17 02:00:00+00'::timestamptz,
    '2026-02-17 04:00:00+00'::timestamptz,
    10.0
)::observer_window;
RESET enable_indexscan;
RESET enable_bitmapscan;

SET enable_seqscan = off;
CREATE TEMPORARY TABLE idx_results AS
SELECT norad_id FROM bench_catalog
WHERE tle &? ROW(
    observer('43.6977N 116.3535W 760m'),
    '2026-02-17 02:00:00+00'::timestamptz,
    '2026-02-17 04:00:00+00'::timestamptz,
    10.0
)::observer_window;
RESET enable_seqscan;

-- These should both be 0
SELECT count(*) AS in_seq_not_idx FROM seq_results
WHERE norad_id NOT IN (SELECT norad_id FROM idx_results);

SELECT count(*) AS in_idx_not_seq FROM idx_results
WHERE norad_id NOT IN (SELECT norad_id FROM seq_results);

DROP TABLE seq_results, idx_results;

-- ============================================================
-- 8. EXPLAIN ANALYZE for query plan details
-- ============================================================
\echo '--- EXPLAIN ANALYZE: SP-GiST scan ---'

SET enable_seqscan = off;
EXPLAIN ANALYZE
SELECT count(*)
FROM bench_catalog
WHERE tle &? ROW(
    observer('43.6977N 116.3535W 760m'),
    '2026-02-17 02:00:00+00'::timestamptz,
    '2026-02-17 04:00:00+00'::timestamptz,
    10.0
)::observer_window;
RESET enable_seqscan;

\echo '--- EXPLAIN ANALYZE: Sequential scan ---'

SET enable_indexscan = off;
SET enable_bitmapscan = off;
EXPLAIN ANALYZE
SELECT count(*)
FROM bench_catalog
WHERE tle &? ROW(
    observer('43.6977N 116.3535W 760m'),
    '2026-02-17 02:00:00+00'::timestamptz,
    '2026-02-17 04:00:00+00'::timestamptz,
    10.0
)::observer_window;
RESET enable_indexscan;
RESET enable_bitmapscan;

-- ============================================================
-- Cleanup
-- ============================================================
DROP TABLE bench_catalog;

\timing off
