-- pg_orrery 0.6.0 -> 0.7.0 migration
--
-- Adds SP-GiST orbital trie index for satellite pass prediction.
-- 2-level trie: SMA (L0) + inclination (L1) with query-time RAAN filter.
-- The &? operator answers "might this satellite be visible?"

-- ============================================================
-- observer_window composite type (query parameter bundle)
-- ============================================================

CREATE TYPE observer_window AS (
    obs         observer,
    t_start     timestamptz,
    t_end       timestamptz,
    min_el      float8
);

COMMENT ON TYPE observer_window IS
    'Observation query parameters: observer location, time window, and minimum elevation angle (degrees). Used with the &? visibility cone operator.';

-- ============================================================
-- Visibility cone operator function
-- ============================================================

CREATE FUNCTION tle_visibility_possible(observer_window, tle) RETURNS boolean
    AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION tle_visibility_possible(observer_window, tle) IS
    'Could this satellite be visible from the observer during the time window? Combines altitude, inclination, and RAAN checks. Conservative superset — survivors need SGP4 propagation for ground truth.';

-- ============================================================
-- &? operator (visibility cone check)
-- ============================================================

CREATE OPERATOR &? (
    LEFTARG   = observer_window,
    RIGHTARG  = tle,
    FUNCTION  = tle_visibility_possible,
    RESTRICT  = contsel,
    JOIN      = contjoinsel
);

COMMENT ON OPERATOR &? (observer_window, tle) IS
    'Visibility cone check: could this satellite be visible from the observer during the time window? Index-accelerated via SP-GiST orbital trie.';

-- ============================================================
-- SP-GiST support functions
-- ============================================================

CREATE FUNCTION spgist_tle_config(internal, internal) RETURNS void
    AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

CREATE FUNCTION spgist_tle_choose(internal, internal) RETURNS void
    AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

CREATE FUNCTION spgist_tle_picksplit(internal, internal) RETURNS void
    AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

CREATE FUNCTION spgist_tle_inner_consistent(internal, internal) RETURNS void
    AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

CREATE FUNCTION spgist_tle_leaf_consistent(internal, internal) RETURNS void
    AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

-- ============================================================
-- SP-GiST operator class (opt-in, not DEFAULT)
-- ============================================================

CREATE OPERATOR CLASS tle_spgist_ops
    FOR TYPE tle USING spgist AS
        OPERATOR  1   &? (observer_window, tle),
        FUNCTION  1   spgist_tle_config(internal, internal),
        FUNCTION  2   spgist_tle_choose(internal, internal),
        FUNCTION  3   spgist_tle_picksplit(internal, internal),
        FUNCTION  4   spgist_tle_inner_consistent(internal, internal),
        FUNCTION  5   spgist_tle_leaf_consistent(internal, internal);
