"""
MikoshiLang Extended Functions - Set 27
Aerospace engineering, flight dynamics, and orbital mechanics
"""
import sympy as sp
from sympy import symbols, sqrt, sin, cos, tan, exp, log, pi, atan2

def get_rules():
    """Extended set 27: Aerospace engineering (150 functions)"""
    v, h, M, rho = symbols('v h M rho')
    
    return [
        # ===== AERODYNAMICS (40 functions) =====
        ('LiftForceAero[CL_, rho_, v_, S_]', lambda CL, rho, v, S: sp.Rational(1,2)*CL*rho*v**2*S),
        ('DragForceAero[CD_, rho_, v_, S_]', lambda CD, rho, v, S: sp.Rational(1,2)*CD*rho*v**2*S),
        ('LiftCoefficient[L_, rho_, v_, S_]', lambda L, rho, v, S: 2*L/(rho*v**2*S)),
        ('DragCoefficient[D_, rho_, v_, S_]', lambda D, rho, v, S: 2*D/(rho*v**2*S)),
        ('LiftToDragRatio[CL_, CD_]', lambda CL, CD: CL/CD),
        ('InducedDrag[CL_, AR_, e_]', lambda CL, AR, e: CL**2/(pi*e*AR)),
        ('AspectRatio[b_, S_]', lambda b, S: b**2/S),
        ('OswaldEfficiency[e_]', lambda e: e),
        ('ParasiticDrag[CD0_]', lambda CD0: CD0),
        ('TotalDrag[CD0_, CDi_]', lambda CD0, CDi: CD0 + CDi),
        ('AngleOfAttack[alpha_]', lambda alpha: alpha),
        ('LiftSlope[dCL_d_alpha_]', lambda dCLda: dCLda),
        ('Stall Angle[alpha_stall_]', lambda alphas: alphas),
        ('MaxLiftCoefficient[CL_max_]', lambda CLmax: CLmax),
        ('DynamicPressure[rho_, v_]', lambda rho, v: sp.Rational(1,2)*rho*v**2),
        ('WingLoading[W_, S_]', lambda W, S: W/S),
        ('ThrustLoading[T_, W_]', lambda T, W: T/W),
        ('PowerLoading[P_, W_]', lambda P, W: P/W),
        ('PropulsiveEfficiency[thrust_power_, shaft_power_]', lambda TP, SP: TP/SP),
        ('PropellerEfficiency[T_, v_, P_]', lambda T, v, P: T*v/P),
        ('ThrustSpecificFuelConsumption[fuel_flow_, thrust_]', lambda ff, T: ff/T),
        ('SpecificImpulse[thrust_, fuel_flow_, g_]', lambda T, ff, g: T/(ff*g)),
        ('RangeBreguet[V_, L_D_, c_, W0_, W1_]', lambda V, LD, c, W0, W1: V*LD/c*log(W0/W1)),
        ('EnduranceBreguet[L_D_, c_, W0_, W1_]', lambda LD, c, W0, W1: LD/c*log(W0/W1)),
        ('ClimbRate[T_, D_, W_, v_]', lambda T, D, W, v: (T - D)*v/W),
        ('CeilingAbsolute[climb_rate_]', lambda RC: RC == 0),
        ('ServiceCeiling[climb_rate_]', lambda RC: RC == 100/60),  # ft/min to m/s
        ('GlideRatio[L_D_]', lambda LD: LD),
        ('GlideAngle[L_D_]', lambda LD: atan2(1, LD)),
        ('BestGlideSpeed[L_D_max_]', lambda LDmax: sp.Symbol('v_bestglide')),
        ('TakeoffDistance[v2_, acceleration_]', lambda v2, a: v2**2/(2*a)),
        ('LandingDistance[v_, deceleration_]', lambda v, a: v**2/(2*a)),
        ('TurnRadius[v_, phi_]', lambda v, phi: v**2/(sp.Symbol('g')*tan(phi))),
        ('TurnRate[g_, phi_]', lambda g, phi: g*tan(phi)/sp.Symbol('v')),
        ('LoadFactor[L_, W_]', lambda L, W: L/W),
        ('CornerVelocity[W_, S_, rho_, CL_max_, n_max_]', lambda W, S, rho, CLmax, nmax: sqrt(2*W*nmax/(rho*S*CLmax))),
        ('VManeuver[n_]', lambda n: sqrt(n)*sp.Symbol('V_stall')),
        ('VNeverExceed[VNE_]', lambda VNE: VNE),
        ('VNeDive[VD_]', lambda VD: VD),
        ('CriticalMachNumber[M_crit_]', lambda Mcrit: Mcrit),
        
        # ===== COMPRESSIBLE FLOW (30 functions) =====
        ('MachNumberAero[v_, a_]', lambda v, a: v/a),
        ('SpeedOfSound[gamma_, R_, T_]', lambda gamma, R, T: sqrt(gamma*R*T)),
        ('StagnationTemperatureAero[T_, M_, gamma_]', lambda T, M, gamma: T*(1 + (gamma - 1)/2*M**2)),
        ('StagnationPressureAero[p_, M_, gamma_]', lambda p, M, gamma: p*(1 + (gamma - 1)/2*M**2)**(gamma/(gamma - 1))),
        ('StagnationDensity[rho_, M_, gamma_]', lambda rho, M, gamma: rho*(1 + (gamma - 1)/2*M**2)**(1/(gamma - 1))),
        ('IsentropicRelation[T_, T0_, M_, gamma_]', lambda T, T0, M, gamma: T/T0 == 1/(1 + (gamma - 1)/2*M**2)),
        ('CriticalPressureRatioAero[gamma_]', lambda gamma: (2/(gamma + 1))**(gamma/(gamma - 1))),
        ('ChokedFlowMach[M_]', lambda M: M >= 1),
        ('NormalShockMach[M1_, gamma_]', lambda M1, gamma: sqrt((1 + (gamma - 1)/2*M1**2)/(gamma*M1**2 - (gamma - 1)/2))),
        ('PressureRatioShock[M1_, gamma_]', lambda M1, gamma: 1 + 2*gamma/(gamma + 1)*(M1**2 - 1)),
        ('DensityRatioShock[M1_, gamma_]', lambda M1, gamma: ((gamma + 1)*M1**2)/((gamma - 1)*M1**2 + 2)),
        ('TemperatureRatioShock[M1_, gamma_]', lambda M1, gamma: (1 + 2*gamma/(gamma + 1)*(M1**2 - 1))*((gamma - 1)*M1**2 + 2)/((gamma + 1)*M1**2)),
        ('ObliqueShockAngle[M1_, beta_, gamma_]', lambda M1, beta, gamma: atan2(2*(M1**2*sin(beta)**2 - 1)*cos(beta), (M1**2*(gamma + cos(2*beta)) + 2))),
        ('ShockWaveAngle[M1_, theta_, gamma_]', lambda M1, theta, gamma: sp.Symbol('beta')),  # Iterative solution
        ('PrandtlMeyerAngle[M_, gamma_]', lambda M, gamma: sqrt((gamma + 1)/(gamma - 1))*atan2(sqrt((gamma - 1)/(gamma + 1)*(M**2 - 1)), 1) - atan2(sqrt(M**2 - 1), 1)),
        ('ExpansionWaveTurn[M1_, M2_, gamma_]', lambda M1, M2, gamma: sp.Symbol('nu2') - sp.Symbol('nu1')),
        ('RayleighFlowAero[M_, gamma_]', lambda M, gamma: (1 + gamma*M**2)/(1 + gamma)),
        ('FannoFlowAero[M_, gamma_]', lambda M, gamma: M*sqrt((gamma + 1)/(2 + (gamma - 1)*M**2))),
        ('AreaMachNumber[A_, A_star_, M_, gamma_]', lambda A, Astar, M, gamma: A/Astar - 1/M*((2 + (gamma - 1)*M**2)/(gamma + 1))**((gamma + 1)/(2*(gamma - 1)))),
        ('MassFlowRate[rho_, A_, v_]', lambda rho, A, v: rho*A*v),
        ('MassFlowRateChoked[A_, p0_, T0_, gamma_, R_]', lambda A, p0, T0, gamma, R: A*p0*sqrt(gamma/(R*T0))*(2/(gamma + 1))**((gamma + 1)/(2*(gamma - 1)))),
        ('NozzleThrust[mdot_, ve_, pe_, pa_, Ae_]', lambda mdot, ve, pe, pa, Ae: mdot*ve + (pe - pa)*Ae),
        ('ExitVelocity[gamma_, R_, T0_, pe_, p0_]', lambda gamma, R, T0, pe, p0: sqrt(2*gamma*R*T0/(gamma - 1)*(1 - (pe/p0)**((gamma - 1)/gamma)))),
        ('NozzleExpansionRatio[pe_, p0_]', lambda pe, p0: p0/pe),
        ('ConeDeCLaval[A_throat_, A_exit_]', lambda At, Ae: Ae/At),
        ('SupersonicNozzleArea[M_, A_star_, gamma_]', lambda M, Astar, gamma: Astar/M*((2 + (gamma - 1)*M**2)/(gamma + 1))**((gamma + 1)/(2*(gamma - 1)))),
        ('SubsonicDiffuserArea[M1_, M2_]', lambda M1, M2: M1/M2),
        ('InletPressureRecovery[p02_, p01_]', lambda p02, p01: p02/p01),
        ('RamEffect[v_]', lambda v: sp.Rational(1,2)*sp.Symbol('rho')*v**2),
        ('IntakeEfficiency[p02_, p0_]', lambda p02, p0: p02/p0),
        
        # ===== PROPULSION (30 functions) =====
        ('RocketEquation[delta_v_, ve_, m0_, mf_]', lambda dv, ve, m0, mf: dv - ve*log(m0/mf)),
        ('TsiolkovskyEquation[ve_, m0_, mf_]', lambda ve, m0, mf: ve*log(m0/mf)),
        ('ExhaustVelocity[Isp_, g0_]', lambda Isp, g0: Isp*g0),
        ('SpecificImpulseRocket[ve_, g0_]', lambda ve, g0: ve/g0),
        ('MassRatio[m0_, mf_]', lambda m0, mf: m0/mf),
        ('PropellantMassFraction[mp_, m0_]', lambda mp, m0: mp/m0),
        ('PayloadFraction[mpayload_, m0_]', lambda mpay, m0: mpay/m0),
        ('BurnTime[mp_, mdot_]', lambda mp, mdot: mp/mdot),
        ('ThrustRocket[mdot_, ve_, pe_, pa_, Ae_]', lambda mdot, ve, pe, pa, Ae: mdot*ve + (pe - pa)*Ae),
        ('ThrustCoefficient[T_, pc_, At_]', lambda T, pc, At: T/(pc*At)),
        ('CharacteristicVelocity[pc_, At_, mdot_]', lambda pc, At, mdot: pc*At/mdot),
        ('C_StarEfficiency[c_star_actual_, c_star_theoretical_]', lambda ca, ct: ca/ct),
        ('NozzleEfficiency[ve_actual_, ve_ideal_]', lambda vea, vei: vea/vei),
        ('CombustionEfficiency[c_star_actual_, c_star_theoretical_]', lambda ca, ct: ca/ct),
        ('ThrottleRatio[T_min_, T_max_]', lambda Tmin, Tmax: Tmin/Tmax),
        ('MixtureRatio[oxidizer_flow_, fuel_flow_]', lambda ox, fu: ox/fu),
        ('ChamberPressure[pc_]', lambda pc: pc),
        ('NozzleExpansionRatioOptimal[pa_, pc_, gamma_]', lambda pa, pc, gamma: ((gamma + 1)/2)**(gamma/(gamma - 1))*(pa/pc)**((gamma - 1)/gamma)),
        ('CombustionTemperature[Q_, cp_]', lambda Q, cp: Q/cp),
        ('AdiabaticFlameTemperature[reactants_, products_]', lambda r, p: sp.Symbol('T_flame')),
        ('TurbojetThrust[mdot_, ve_, v0_]', lambda mdot, ve, v0: mdot*(ve - v0)),
        ('TurbofanBypassRatio[m_bypass_, m_core_]', lambda mb, mc: mb/mc),
        ('OverallPressureRatio[p03_, p02_]', lambda p03, p02: p03/p02),
        ('TurbineInletTemperature[T04_]', lambda T04: T04),
        ('CompressorEfficiency[eta_c_]', lambda etac: etac),
        ('TurbineEfficiency[eta_t_]', lambda etat: etat),
        ('ThermalEfficiency[W_net_, Q_in_]', lambda Wnet, Qin: Wnet/Qin),
        ('PropulsiveEfficiencyJet[T_, v0_, mdot_, ve_]', lambda T, v0, mdot, ve: 2*v0/(v0 + ve)),
        ('RamjetEfficiency[v0_, ve_]', lambda v0, ve: 2*v0/(v0 + ve)),
        ('ScramjetOperation[M_]', lambda M: M > 5),
        
        # ===== ORBITAL MECHANICS (50 functions) =====
        ('OrbitalVelocity[mu_, r_]', lambda mu, r: sqrt(mu/r)),
        ('CircularOrbitVelocity[mu_, r_]', lambda mu, r: sqrt(mu/r)),
        ('EscapeVelocityOrbit[mu_, r_]', lambda mu, r: sqrt(2*mu/r)),
        ('SemiMajorAxisOrbit[r_periapsis_, r_apoapsis_]', lambda rp, ra: (rp + ra)/2),
        ('EccentricityOrbit[r_periapsis_, r_apoapsis_]', lambda rp, ra: (ra - rp)/(ra + rp)),
        ('OrbitalPeriod[a_, mu_]', lambda a, mu: 2*pi*sqrt(a**3/mu)),
        ('MeanMotion[mu_, a_]', lambda mu, a: sqrt(mu/a**3)),
        ('SpecificOrbitalEnergy[v_, r_, mu_]', lambda v, r, mu: v**2/2 - mu/r),
        ('SpecificAngularMomentumOrbit[r_, v_, gamma_]', lambda r, v, gamma: r*v*cos(gamma)),
        ('FlightPathAngle[v_r_, v_t_]', lambda vr, vt: atan2(vr, vt)),
        ('TrueAnomalyOrbit[r_, a_, e_]', lambda r, a, e: sp.acos((a*(1 - e**2)/r - 1)/e)),
        ('EccentricAnomalyOrbit[E_, e_]', lambda E, e: E - e*sin(E)),  # Kepler's equation
        ('MeanAnomalyOrbit[M_, e_, E_]', lambda M, e, E: M - E + e*sin(E)),
        ('TimeOfFlight[M_, n_]', lambda M, n: M/n),
        ('HohmannTransferDeltaV[r1_, r2_, mu_]', lambda r1, r2, mu: sqrt(mu/r1)*(sqrt(2*r2/(r1 + r2)) - 1) + sqrt(mu/r2)*(1 - sqrt(2*r1/(r1 + r2)))),
        ('BiellipticTransferDeltaV[r1_, r2_, rb_, mu_]', lambda r1, r2, rb, mu: sqrt(mu/r1)*(sqrt(2*rb/(r1 + rb)) - 1)),
        ('PhaseAngleHohmann[a1_, a2_, mu_]', lambda a1, a2, mu: pi*(1 - sqrt((a1 + a2)**3/(8*a2**3)))),
        ('InclinationChange[v_, delta_i_]', lambda v, di: 2*v*sin(di/2)),
        ('PlaneChangeDeltaV[v_, delta_i_]', lambda v, di: 2*v*sin(di/2)),
        ('NodeRotation[delta_RAAN_]', lambda dRAAN: dRAAN),
        ('ArgumentOfPeriapsisChange[delta_omega_]', lambda dom: dom),
        ('SynodicPeriodOrbit[P1_, P2_]', lambda P1, P2: abs(1/(1/P1 - 1/P2))),
        ('HillSphereRadius[a_, M_primary_, m_satellite_]', lambda a, M, m: a*(m/(3*M))**sp.Rational(1,3)),
        ('RocheLimitRigid[R_primary_, rho_primary_, rho_satellite_]', lambda R, rhop, rhos: 2.46*R*(rhop/rhos)**sp.Rational(1,3)),
        ('RocheLimitFluid[R_primary_, rho_primary_, rho_satellite_]', lambda R, rhop, rhos: 2.88*R*(rhop/rhos)**sp.Rational(1,3)),
        ('SphereOfInfluenceRadius[a_, M_primary_, m_satellite_]', lambda a, M, m: a*(m/M)**sp.Rational(2,5)),
        ('LagrangePointL1[a_, M1_, M2_]', lambda a, M1, M2: a*(1 - (M2/(3*M1))**sp.Rational(1,3))),
        ('LagrangePointL2[a_, M1_, M2_]', lambda a, M1, M2: a*(1 + (M2/(3*M1))**sp.Rational(1,3))),
        ('LagrangePointL3[a_, M1_, M2_]', lambda a, M1, M2: -a*(1 + 5*M2/(12*M1))),
        ('LagrangePointL4L5[a_]', lambda a: a),  # 60° ahead/behind
        ('HaloOrbit[L1_, amplitude_]', lambda L1, A: (L1, A)),
        ('LissajousOrbit[Ax_, Ay_, Az_]', lambda Ax, Ay, Az: (Ax, Ay, Az)),
        ('ThreeBodyProblem[m1_, m2_, m3_]', lambda m1, m2, m3: "numerical"),
        ('PatchedConicApproximation[trajectory_]', lambda traj: traj),
        ('GravityAssist[v_inf_in_, v_inf_out_]', lambda vin, vout: vout - vin),
        ('SlingshottEffect[v_, v_planet_]', lambda v, vp: v + 2*vp),
        ('OberthEffect[delta_v_, r_]', lambda dv, r: dv*sqrt(2*sp.Symbol('mu')/r)),
        ('VisVivaEquationOrbit[v_, r_, a_, mu_]', lambda v, r, a, mu: v**2 - mu*(2/r - 1/a)),
        ('OrbitalDecay[delta_a_, drag_]', lambda da, drag: da == -drag),
        ('AtmosphericDragOrbit[CD_, A_, rho_, v_]', lambda CD, A, rho, v: sp.Rational(1,2)*CD*A*rho*v**2),
        ('BallisticCoefficient[m_, CD_, A_]', lambda m, CD, A: m/(CD*A)),
        ('ReentryHeating[rho_, v_]', lambda rho, v: rho*v**3),
        ('PeriapsisChange[delta_v_, e_, nu_]', lambda dv, e, nu: dv*sin(nu)*(1 + e*cos(nu))),
        ('ApoapsisChange[delta_v_, e_, nu_]', lambda dv, e, nu: dv*sin(nu)*(1 + e*cos(nu))),
        ('GroundTrack[i_, RAAN_, omega_, nu_]', lambda i, RAAN, omega, nu: (sp.Symbol('lat'), sp.Symbol('lon'))),
        ('SubsatellitePoint[r_, i_, RAAN_]', lambda r, i, RAAN: (sp.asin(sin(i)*sin(sp.Symbol('u'))), RAAN + atan2(cos(i)*sin(sp.Symbol('u')), cos(sp.Symbol('u'))))),
        ('SwathWidth[h_, theta_]', lambda h, theta: 2*h*tan(theta)),
        ('RevisitTime[period_, coverage_]', lambda T, cov: T/cov),
        ('ConstellationCoverage[n_sats_, n_planes_]', lambda ns, np: ns*np),
    ]


def register():
    """Register all extended27 rules"""
    from .extended_helper import convert_rules
    return convert_rules(get_rules())
