-- moon_observe regression tests
--
-- Tests planetary moon observation (Galilean, Saturn, Uranus, Mars)
-- and Jupiter decametric radio burst prediction functions.
-- Reference distances from JPL/NASA fact sheets.

\set boulder '''40.015N 105.270W 1655m'''::observer

-- ============================================================
-- Test 1: Galilean moon observation - all four from Boulder
-- Io, Europa, Ganymede, Callisto should return valid topocentric.
-- ============================================================
SELECT 'galilean_io' AS test,
       round(topo_azimuth(galilean_observe(0, :boulder,
             '2024-03-15 03:00:00+00'))::numeric, 0) AS az_deg,
       round(topo_elevation(galilean_observe(0, :boulder,
             '2024-03-15 03:00:00+00'))::numeric, 0) AS el_deg;

SELECT 'galilean_europa' AS test,
       round(topo_azimuth(galilean_observe(1, :boulder,
             '2024-03-15 03:00:00+00'))::numeric, 0) AS az_deg,
       round(topo_elevation(galilean_observe(1, :boulder,
             '2024-03-15 03:00:00+00'))::numeric, 0) AS el_deg;

SELECT 'galilean_ganymede' AS test,
       round(topo_azimuth(galilean_observe(2, :boulder,
             '2024-03-15 03:00:00+00'))::numeric, 0) AS az_deg,
       round(topo_elevation(galilean_observe(2, :boulder,
             '2024-03-15 03:00:00+00'))::numeric, 0) AS el_deg;

SELECT 'galilean_callisto' AS test,
       round(topo_azimuth(galilean_observe(3, :boulder,
             '2024-03-15 03:00:00+00'))::numeric, 0) AS az_deg,
       round(topo_elevation(galilean_observe(3, :boulder,
             '2024-03-15 03:00:00+00'))::numeric, 0) AS el_deg;

-- ============================================================
-- Test 2: Galilean moons should be very close to Jupiter
-- All four should have ranges within ~0.05 AU of Jupiter's range.
-- Jupiter is ~4-6 AU from Earth; moons orbit within 0.013 AU.
-- ============================================================
SELECT 'galilean_near_jupiter' AS test,
       round(topo_range(planet_observe(5, :boulder,
             '2024-03-15 03:00:00+00'))::numeric, -4) AS jupiter_km,
       round(topo_range(galilean_observe(0, :boulder,
             '2024-03-15 03:00:00+00'))::numeric, -4) AS io_km,
       round(topo_range(galilean_observe(3, :boulder,
             '2024-03-15 03:00:00+00'))::numeric, -4) AS callisto_km;

-- ============================================================
-- Test 3: Saturn moon observation - Titan (body_id=5)
-- Titan is Saturn's largest moon, should be near Saturn.
-- ============================================================
SELECT 'saturn_titan' AS test,
       round(topo_azimuth(saturn_moon_observe(5, :boulder,
             '2024-06-15 03:00:00+00'))::numeric, 0) AS az_deg,
       round(topo_elevation(saturn_moon_observe(5, :boulder,
             '2024-06-15 03:00:00+00'))::numeric, 0) AS el_deg;

-- ============================================================
-- Test 4: Saturn moons - Mimas through Iapetus all return results
-- ============================================================
SELECT 'saturn_moons' AS test,
       body_id,
       round(topo_range(saturn_moon_observe(body_id, :boulder,
             '2024-06-15 03:00:00+00'))::numeric, -4) AS range_km
FROM generate_series(0, 7) AS body_id;

-- ============================================================
-- Test 5: Uranus moon observation - Titania (body_id=3)
-- ============================================================
SELECT 'uranus_titania' AS test,
       round(topo_azimuth(uranus_moon_observe(3, :boulder,
             '2024-06-15 03:00:00+00'))::numeric, 0) AS az_deg,
       round(topo_elevation(uranus_moon_observe(3, :boulder,
             '2024-06-15 03:00:00+00'))::numeric, 0) AS el_deg;

-- ============================================================
-- Test 6: All Uranus moons return valid results
-- ============================================================
SELECT 'uranus_moons' AS test,
       body_id,
       round(topo_range(uranus_moon_observe(body_id, :boulder,
             '2024-06-15 03:00:00+00'))::numeric, -4) AS range_km
FROM generate_series(0, 4) AS body_id;

-- ============================================================
-- Test 7: Mars moons - Phobos and Deimos
-- ============================================================
SELECT 'mars_phobos' AS test,
       round(topo_azimuth(mars_moon_observe(0, :boulder,
             '2024-01-15 06:00:00+00'))::numeric, 0) AS az_deg,
       round(topo_elevation(mars_moon_observe(0, :boulder,
             '2024-01-15 06:00:00+00'))::numeric, 0) AS el_deg;

SELECT 'mars_deimos' AS test,
       round(topo_azimuth(mars_moon_observe(1, :boulder,
             '2024-01-15 06:00:00+00'))::numeric, 0) AS az_deg,
       round(topo_elevation(mars_moon_observe(1, :boulder,
             '2024-01-15 06:00:00+00'))::numeric, 0) AS el_deg;

-- ============================================================
-- Test 8: Io phase angle - should be [0, 360)
-- ============================================================
SELECT 'io_phase' AS test,
       round(io_phase_angle('2024-03-15 03:00:00+00')::numeric, 1) AS phase_deg,
       io_phase_angle('2024-03-15 03:00:00+00') >= 0.0
           AND io_phase_angle('2024-03-15 03:00:00+00') < 360.0 AS in_range;

-- ============================================================
-- Test 9: Jupiter CML (System III) - should be [0, 360)
-- ============================================================
SELECT 'jupiter_cml' AS test,
       round(jupiter_cml(:boulder, '2024-03-15 03:00:00+00')::numeric, 1) AS cml_deg,
       jupiter_cml(:boulder, '2024-03-15 03:00:00+00') >= 0.0
           AND jupiter_cml(:boulder, '2024-03-15 03:00:00+00') < 360.0 AS in_range;

-- ============================================================
-- Test 10: Jupiter burst probability - known high probability zone
-- Source A: CML 200-260, Io phase 195-265 => p=0.8
-- ============================================================
SELECT 'burst_source_a' AS test,
       jupiter_burst_probability(230.0, 230.0) AS p_source_a;

-- ============================================================
-- Test 11: Jupiter burst probability - known zones
-- ============================================================
SELECT 'burst_zones' AS test,
       jupiter_burst_probability(90.0, 150.0) AS p_source_b,
       jupiter_burst_probability(240.0, 350.0) AS p_source_c,
       jupiter_burst_probability(100.0, 25.0) AS p_source_d,
       jupiter_burst_probability(0.0, 130.0) AS p_quiet;

-- ============================================================
-- Test 12: Io phase changes over time (Io orbits in ~1.77 days)
-- Two times 12 hours apart should show significant phase change.
-- ============================================================
SELECT 'io_phase_changes' AS test,
       round(io_phase_angle('2024-03-15 00:00:00+00')::numeric, 1) AS phase_0h,
       round(io_phase_angle('2024-03-15 12:00:00+00')::numeric, 1) AS phase_12h,
       abs(io_phase_angle('2024-03-15 00:00:00+00') -
           io_phase_angle('2024-03-15 12:00:00+00')) > 10.0 AS changed;

-- ============================================================
-- Test 13: Error handling - invalid Galilean moon body_id
-- ============================================================
SELECT 'invalid_galilean' AS test, galilean_observe(4, :boulder, now());

-- ============================================================
-- Test 14: Error handling - invalid Saturn moon body_id
-- ============================================================
SELECT 'invalid_saturn' AS test, saturn_moon_observe(8, :boulder, now());
