# Use the existing connected PyFluent variable solver.
task_directory = r"C:\Users\13977\AppData\Local\FluentAGI\data\runs\20261024-125011-fe110c"
original_directory = r"C:\Users\13977\AppData\Local\FluentAGI\data\runs\20261024-124531-c0129e"

def require_ok(result, operation):
    print(result)
    if isinstance(result, dict):
        if result.get("status") in ("error", "failed"):
            raise RuntimeError(operation + " failed; inspect returned evidence")
        if result.get("success") is False or result.get("ok") is False:
            raise RuntimeError(operation + " failed; inspect returned evidence")
        if result.get("error") or result.get("errors"):
            raise RuntimeError(operation + " reported errors")
    return result

try:
    inspection = fluentagi.inspect_execution(directory=original_directory)
    print(inspection)
    if not isinstance(inspection, dict):
        raise RuntimeError("Actual execution state is unavailable")
    state = inspection.get("actual_state", {})
    if state.get("model_active") is not True:
        raise RuntimeError("The existing carrier mesh is unavailable")
    if state.get("has_solution_data") is not True:
        raise RuntimeError("The existing air solution is unavailable")
    if state.get("multiphase_model") != "none":
        raise RuntimeError("Single-phase carrier was not confirmed")

    print(fluentagi.inspect_dpm())

    if solver.settings.setup.general.solver.time.get_state() != "steady":
        raise RuntimeError("This script requires the existing steady carrier")

    boundaries = solver.settings.setup.boundary_conditions
    actual_inlets = list(boundaries.velocity_inlet.get_object_names())
    actual_outlets = list(boundaries.pressure_outlet.get_object_names())
    actual_walls = list(boundaries.wall.get_object_names())
    print({
        "velocity_inlets": actual_inlets,
        "pressure_outlets": actual_outlets,
        "walls": actual_walls
    })
    if set(actual_inlets) != {"inlet"}:
        raise RuntimeError("Inlet names differ from the completed swirl model")
    if set(actual_outlets) != {"outlet"}:
        raise RuntimeError("Outlet names differ from the completed swirl model")
    if set(actual_walls) != {"walls"}:
        raise RuntimeError("Wall names differ from the completed swirl model")

    print({
        "inlet_state": boundaries.velocity_inlet["inlet"].get_state(),
        "carrier_viscous_model":
            solver.settings.setup.models.viscous.model.get_state()
    })

    require_ok(
        fluentagi.backup_loaded(directory=task_directory),
        "Carrier backup"
    )

    injections = []
    for index, offset in enumerate((-0.008, 0.0, 0.008)):
        name = "swirl_dust_10um_row_" + str(index + 1)
        result = fluentagi.create_dust_injection(
            directory=task_directory,
            name=name,
            start=[0.065, 0.036 + offset, -0.159],
            end=[0.085, 0.036 + offset, -0.159],
            streams=12,
            diameter=0.00001,
            mass_flow=0.00000001,
            velocity=[0.0, 0.0, 1.0],
            material="agi-dust",
            density=2500
        )
        require_ok(result, "Injection " + name)
        injections.append(name)

    require_ok(
        fluentagi.configure_dpm(
            directory=task_directory,
            density=2500,
            material="agi-dust",
            max_steps=20000
        ),
        "Steady one-way DPM configuration"
    )

    require_ok(
        fluentagi.set_particle_boundaries(
            directory=task_directory,
            boundaries={
                "inlet": "escape",
                "outlet": "escape",
                "walls": "trap"
            }
        ),
        "Particle boundary configuration"
    )

    print(fluentagi.inspect_dpm())
    print(fluentagi.stage(
        directory=task_directory,
        name="particle_tracking",
        status="running",
        injections=injections,
        nominal_streams=36,
        carrier_recomputed=False,
        animation_type="steady trajectory residence-time replay"
    ))

    tracks = fluentagi.track_particles(
        directory=task_directory,
        injections=injections,
        frames=20
    )
    require_ok(tracks, "Native particle tracking and export")

    print(fluentagi.save_case_data_safe(
        task_directory + r"\swirl_with_particles.cas.h5"
    ))

    assessment = {
        "carrier_directory": original_directory,
        "particle_directory": task_directory,
        "carrier_reinitialized": False,
        "carrier_recomputed": False,
        "particle_model": "one-way steady inert DPM",
        "diameter_m": 0.00001,
        "density_kg_m3": 2500,
        "total_injected_mass_flow_kg_s": 0.00000003,
        "nominal_numerical_streams": 36,
        "injection_velocity_m_s": [0.0, 0.0, 1.0],
        "wall_behavior": "trap",
        "animation_label": "稳态轨迹回放",
        "physical_particle_count": "not represented by numerical stream count",
        "stochastic_turbulent_dispersion": "not configured",
        "carrier_convergence_verified": False,
        "collection_efficiency_validated": False,
        "particle_accounting": "refer to native tracker counts and mass summary",
        "tracking_result": tracks,
        "needs_review": True
    }
    print(fluentagi.write_json(
        directory=task_directory,
        name="particle-assessment.json",
        data=assessment
    ))
    print(fluentagi.stage(
        directory=task_directory,
        name="particle_tracking",
        status="completed",
        carrier_convergence_verified=False,
        needs_review=True
    ))

except Exception as exc:
    print({"status": "stopped", "error": str(exc)})
    for directory in (original_directory, task_directory):
        print(fluentagi.inspect_execution(directory=directory))
    raise