-- Test TLE type: parsing, round-trip, accessors
CREATE EXTENSION IF NOT EXISTS pg_orrery;

-- Parse a valid ISS TLE
SELECT '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'::tle IS NOT NULL AS parse_ok;

-- Accessor functions
WITH iss AS (
    SELECT '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'::tle AS t
)
SELECT
    tle_norad_id(t) AS norad_id,
    round(tle_inclination(t)::numeric, 4) AS inc_deg,
    round(tle_eccentricity(t)::numeric, 7) AS ecc,
    round(tle_mean_motion(t)::numeric, 8) AS mm_rev_day,
    round(tle_period(t)::numeric, 2) AS period_min,
    round(tle_perigee(t)::numeric, 1) AS perigee_km,
    round(tle_apogee(t)::numeric, 1) AS apogee_km,
    tle_intl_desig(t) AS cospar
FROM iss;

-- Observer type parsing
SELECT '40.0N 105.3W 1655m'::observer IS NOT NULL AS observer_ok;
SELECT observer_lat('40.0N 105.3W 1655m'::observer) AS lat,
       observer_lon('40.0N 105.3W 1655m'::observer) AS lon;

-- ECI type parsing
SELECT '(1000.0,2000.0,3000.0,1.0,2.0,3.0)'::eci_position IS NOT NULL AS eci_ok;
SELECT eci_x('(1000.0,2000.0,3000.0,1.0,2.0,3.0)'::eci_position) AS x;

-- SGP4 propagation at epoch
WITH iss AS (
    SELECT '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'::tle AS t
)
SELECT
    round(eci_speed(sgp4_propagate(t, '2024-01-01 12:00:00+00'))::numeric, 2) AS speed_kms,
    round(eci_altitude(sgp4_propagate(t, '2024-01-01 12:00:00+00'))::numeric, 0) AS alt_km
FROM iss;

-- Altitude overlap operator
WITH sats AS (
    SELECT '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'::tle AS iss,
    '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'::tle AS gps
)
SELECT
    iss && iss AS same_overlap,
    iss && gps AS different_no_overlap
FROM sats;

-- Subsatellite point
WITH iss AS (
    SELECT '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'::tle AS t
)
SELECT
    round(geodetic_lat(subsatellite_point(t, '2024-01-01 12:00:00+00'))::numeric, 2) AS lat,
    round(geodetic_alt(subsatellite_point(t, '2024-01-01 12:00:00+00'))::numeric, 0) AS alt_km
FROM iss;

-- GiST index creation
CREATE TABLE test_sats (id serial, tle tle);
INSERT INTO test_sats (tle) VALUES (
    '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');
CREATE INDEX test_sats_gist ON test_sats USING gist (tle);
SELECT count(*) FROM test_sats WHERE tle && (
    '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'::tle);
DROP TABLE test_sats;
