-- Test GiST index and operators (2-D: altitude + inclination)
CREATE EXTENSION IF NOT EXISTS pg_orrery;

-- Create test table with mixed orbit types
CREATE TABLE test_orbits (
    id serial,
    name text,
    tle tle
);

-- ISS (LEO, ~400km, inclination 51.64 deg)
INSERT INTO test_orbits (name, tle) VALUES ('ISS',
    '1 25544U 98067A   24001.50000000  .00016717  00000-0  10270-3 0  9025
2 25544  51.6400 208.9163 0006703  30.1694  61.7520 15.50100486 00001');

-- Hubble (LEO, ~540km, inclination 28.47 deg)
INSERT INTO test_orbits (name, tle) VALUES ('Hubble',
    '1 20580U 90037B   24001.50000000  .00000790  00000+0  39573-4 0  9992
2 20580  28.4705  61.4398 0002797 317.3115  42.7577 15.09395228 00008');

-- GPS IIR-M (MEO, ~20200km, inclination 55.44 deg)
INSERT INTO test_orbits (name, tle) VALUES ('GPS-IIR',
    '1 28874U 05038A   24001.50000000  .00000012  00000+0  00000+0 0  9993
2 28874  55.4408 300.3467 0117034  51.6543 309.5420  2.00557079 00006');

-- Equatorial-LEO: same altitude as ISS but near-equatorial inclination (5 deg).
-- Same mean motion (15.501 rev/day) and eccentricity as ISS → same altitude band.
-- Different inclination → should NOT overlap with ISS under 2-D key.
INSERT INTO test_orbits (name, tle) VALUES ('Equatorial-LEO',
    '1 99901U 24999A   24001.50000000  .00016717  00000-0  10270-3 0  9990
2 99901   5.0000 208.9163 0006703  30.1694  61.7520 15.50100486 00001');

-- Create GiST index
CREATE INDEX test_orbits_gist ON test_orbits USING gist (tle);

-- 2-D overlap: ISS && Equatorial-LEO should be false (same altitude, different inclination)
SELECT a.name AS sat_a, b.name AS sat_b, a.tle && b.tle AS overlaps
FROM test_orbits a, test_orbits b
WHERE a.id < b.id
ORDER BY a.name, b.name;

-- Orbital distance: 2-D metric (altitude + inclination in km)
-- ISS <-> Equatorial-LEO should be ~5192 (0 km alt gap + 47° inc diff × 6378 km)
SELECT a.name AS sat_a, b.name AS sat_b,
       round((a.tle <-> b.tle)::numeric, 0) AS orbital_dist_km
FROM test_orbits a, test_orbits b
WHERE a.id < b.id
ORDER BY a.name, b.name;

-- GiST index scan: find all sats overlapping ISS (altitude AND inclination)
-- Should return only ISS itself (Equatorial-LEO is at same altitude but wrong inclination)
SET enable_seqscan = off;
SELECT name FROM test_orbits
WHERE tle && (SELECT tle FROM test_orbits WHERE name = 'ISS')
ORDER BY name;
RESET enable_seqscan;

-- Nearest-neighbor via GiST: order by 2-D orbital distance to ISS
SET enable_seqscan = off;
SELECT name, round((tle <-> (SELECT tle FROM test_orbits WHERE name = 'ISS'))::numeric, 0) AS dist
FROM test_orbits
WHERE name != 'ISS'
ORDER BY tle <-> (SELECT tle FROM test_orbits WHERE name = 'ISS');
RESET enable_seqscan;

-- Self-overlap is always true
SELECT name, tle && tle AS self_overlap FROM test_orbits ORDER BY name;

-- Cleanup
DROP TABLE test_orbits;
