-- pg_orrery 0.3.0 -> 0.4.0 migration
--
-- Adds observation-to-TLE fitting via batch weighted least-squares
-- differential correction (Vallado & Crawford 2008, AIAA 2008-6770).
-- Uses equinoctial elements internally for singularity-free optimization.
-- LAPACK dgelss_() for SVD solve.

-- ============================================================
-- Phase 6: Orbit determination (TLE fitting from observations)
-- ============================================================

-- Fit TLE from ECI position/velocity ephemeris

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
) 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, and convergence status. Requires >= 6 observations.';

-- Fit TLE from topocentric observations (az/el/range)

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
) 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. Requires seed TLE and >= 6 observations.';

-- Per-observation residuals diagnostic

CREATE FUNCTION tle_fit_residuals(
    fitted tle,
    positions eci_position[],
    times timestamptz[]
) RETURNS TABLE (
    t timestamptz,
    dx_km float8,
    dy_km float8,
    dz_km float8,
    pos_err_km float8
)
    AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION tle_fit_residuals(tle, eci_position[], timestamptz[]) IS
    'Compute per-observation position residuals (km) between a TLE and ECI observations. Useful for fit quality assessment.';
