-- convenience functions requested by Craft (Astrolock) integration
CREATE EXTENSION IF NOT EXISTS pg_orrery;

-- tle_from_lines: two-argument constructor
SELECT tle_norad_id(tle_from_lines(
  '1 25544U 98067A   24001.50000000  .00016717  00000-0  10270-3 0  9002',
  '2 25544  51.6400 208.5000 0007417  68.5000 291.5000 15.49560000100001'
)) AS iss_norad_id;

-- observer_from_geodetic: numeric constructor
SELECT observer_from_geodetic(40.0, -105.3, 1655);

-- observer_from_geodetic: default altitude = 0
SELECT observer_from_geodetic(40.0, -105.3);

-- sgp4_propagate_safe: normal propagation returns result
SELECT (sgp4_propagate_safe(
  '1 25544U 98067A   24001.50000000  .00016717  00000-0  10270-3 0  9002
2 25544  51.6400 208.5000 0007417  68.5000 291.5000 15.49560000100001'::tle,
  '2024-01-01 12:00:00+00'::timestamptz
) IS NOT NULL) AS safe_returns_result;

-- sgp4_propagate_safe: diverged orbit returns NULL
SELECT sgp4_propagate_safe(
  '1 25544U 98067A   24001.50000000  .00016717  00000-0  10270-3 0  9002
2 25544  51.6400 208.5000 0007417  68.5000 291.5000 15.49560000100001'::tle,
  '2124-01-01 12:00:00+00'::timestamptz
) IS NULL AS safe_null_on_diverge;

-- observe: single-call propagate + topocentric
SELECT observe(
  '1 25544U 98067A   24001.50000000  .00016717  00000-0  10270-3 0  9002
2 25544  51.6400 208.5000 0007417  68.5000 291.5000 15.49560000100001'::tle,
  observer_from_geodetic(40.0, -105.3, 1655),
  '2024-01-01 12:00:00+00'::timestamptz
);

-- observe_safe: returns NULL on diverged orbit
SELECT observe_safe(
  '1 25544U 98067A   24001.50000000  .00016717  00000-0  10270-3 0  9002
2 25544  51.6400 208.5000 0007417  68.5000 291.5000 15.49560000100001'::tle,
  '40.0N 105.3W 1655m'::observer,
  '2124-01-01 12:00:00+00'::timestamptz
) IS NULL AS observe_safe_null;

-- observe matches manual eci_to_topocentric pipeline
-- (verify observe() produces same result as the two-step approach)
WITH propagated AS (
  SELECT sgp4_propagate(
    '1 25544U 98067A   24001.50000000  .00016717  00000-0  10270-3 0  9002
2 25544  51.6400 208.5000 0007417  68.5000 291.5000 15.49560000100001'::tle,
    '2024-01-01 12:00:00+00'::timestamptz
  ) AS eci
),
manual AS (
  SELECT eci_to_topocentric(
    eci,
    '40.0N 105.3W 1655m'::observer,
    '2024-01-01 12:00:00+00'::timestamptz
  ) AS topo
  FROM propagated
),
single_call AS (
  SELECT observe(
    '1 25544U 98067A   24001.50000000  .00016717  00000-0  10270-3 0  9002
2 25544  51.6400 208.5000 0007417  68.5000 291.5000 15.49560000100001'::tle,
    '40.0N 105.3W 1655m'::observer,
    '2024-01-01 12:00:00+00'::timestamptz
  ) AS topo
)
SELECT
  topo_azimuth(m.topo) = topo_azimuth(s.topo) AS az_match,
  topo_elevation(m.topo) = topo_elevation(s.topo) AS el_match,
  topo_range(m.topo) = topo_range(s.topo) AS range_match
FROM manual m, single_call s;
