-- pg_orrery 0.4.0 -> 0.5.0 migration
--
-- Adds multi-observer support, IOD bootstrap (seed-free fitting),
-- and covariance output for uncertainty estimation.
--
-- Covariance changes the return type of tle_from_eci and
-- tle_from_topocentric (5 → 8 OUT params), which requires
-- DROP + re-CREATE.

-- ============================================================
-- Drop old 5-column OD functions
-- ============================================================

DROP FUNCTION IF EXISTS tle_from_eci(eci_position[], timestamptz[], tle, boolean, int4);
DROP FUNCTION IF EXISTS tle_from_topocentric(topocentric[], timestamptz[], observer, tle, boolean, int4);

-- ============================================================
-- Re-create with 8-column output (adds covariance)
-- ============================================================

CREATE FUNCTION tle_from_eci(
    positions eci_position[], times timestamptz[],
    seed tle DEFAULT NULL, fit_bstar boolean DEFAULT false,
    max_iter int4 DEFAULT 15,
    OUT fitted_tle tle, OUT iterations int4,
    OUT rms_final float8, OUT rms_initial float8, OUT status text,
    OUT condition_number float8, OUT covariance float8[], OUT nstate int4
) RETURNS RECORD
    AS 'MODULE_PATHNAME' LANGUAGE C STABLE PARALLEL SAFE;
COMMENT ON FUNCTION tle_from_eci(eci_position[], timestamptz[], tle, boolean, int4) IS
    'Fit a TLE from ECI position/velocity observations via differential correction. Returns fitted TLE, iteration count, RMS residuals, convergence status, condition number, and formal covariance matrix.';

CREATE FUNCTION tle_from_topocentric(
    observations topocentric[], times timestamptz[],
    obs observer,
    seed tle DEFAULT NULL, fit_bstar boolean DEFAULT false,
    max_iter int4 DEFAULT 15,
    OUT fitted_tle tle, OUT iterations int4,
    OUT rms_final float8, OUT rms_initial float8, OUT status text,
    OUT condition_number float8, OUT covariance float8[], OUT nstate int4
) RETURNS RECORD
    AS 'MODULE_PATHNAME' LANGUAGE C STABLE PARALLEL SAFE;
COMMENT ON FUNCTION tle_from_topocentric(topocentric[], timestamptz[], observer, tle, boolean, int4) IS
    'Fit a TLE from topocentric (az/el/range) observations via differential correction. Returns fitted TLE, RMS residuals, convergence status, condition number, and formal covariance matrix.';

-- ============================================================
-- Multi-observer topocentric fitting (new overload)
-- ============================================================

CREATE FUNCTION tle_from_topocentric(
    observations topocentric[], times timestamptz[],
    observers observer[], observer_ids int4[],
    seed tle DEFAULT NULL, fit_bstar boolean DEFAULT false,
    max_iter int4 DEFAULT 15,
    OUT fitted_tle tle, OUT iterations int4,
    OUT rms_final float8, OUT rms_initial float8, OUT status text,
    OUT condition_number float8, OUT covariance float8[], OUT nstate int4
) RETURNS RECORD
    AS 'MODULE_PATHNAME', 'tle_from_topocentric_multi'
    LANGUAGE C STABLE PARALLEL SAFE;
COMMENT ON FUNCTION tle_from_topocentric(topocentric[], timestamptz[], observer[], int4[], tle, boolean, int4) IS
    'Fit a TLE from topocentric observations collected by multiple ground stations. observer_ids[i] indexes into observers[]. Returns convergence status, condition number, and formal covariance matrix.';
