# Feature: Multi-Flight Graph Lifecycle

## Name
Multi-Flight Graph Lifecycle

## Description
Manages flight-scoped factor graph state for concurrent multi-flight processing. Each flight maintains an independent factor graph (Dict[str, FactorGraph] keyed by flight_id), enabling parallel processing without cross-contamination. Provides cleanup when flights are deleted.

## Component APIs Implemented
- `delete_flight_graph(flight_id) -> bool`

## External Tools and Services
- **GTSAM**: Factor graph instance management

## Internal Methods

### `_get_or_create_flight_graph(flight_id) -> FlightGraphState`
Gets existing flight graph state or creates new one.
- Manages Dict[str, FlightGraphState] internally
- Initializes iSAM2 instance, reference origin, chunk subgraphs
- Thread-safe access

### `_initialize_flight_graph(flight_id) -> FlightGraphState`
Initializes new factor graph state for flight.
- Creates new iSAM2 instance
- Initializes empty chunk subgraph dictionary
- Sets reference origin to None (set on first absolute factor)

### `_cleanup_flight_resources(flight_id) -> bool`
Cleans up all resources associated with flight.
- Removes factor graph from memory
- Cleans up chunk subgraphs
- Clears frame-to-chunk mappings
- Releases GTSAM objects

### `_validate_flight_exists(flight_id) -> bool`
Validates that flight graph exists.
- Returns True if flight_id in graph dictionary
- Used as guard for all operations

### `_get_all_flight_ids() -> List[str]`
Returns list of all active flight IDs.
- Used for administrative/monitoring purposes

### `_get_flight_statistics(flight_id) -> FlightGraphStats`
Returns statistics about flight's factor graph.
- Number of frames, factors, chunks
- Memory usage estimate
- Last optimization time

## Data Structures

### `FlightGraphState`
Internal state container for a flight's factor graph.
```python
class FlightGraphState:
    flight_id: str
    isam2: gtsam.ISAM2
    values: gtsam.Values
    reference_origin: Optional[GPSPoint]  # ENU reference
    chunk_subgraphs: Dict[str, gtsam.NonlinearFactorGraph]
    chunk_values: Dict[str, gtsam.Values]
    frame_to_chunk: Dict[int, str]
    created_at: datetime
    last_optimized: Optional[datetime]
```

### `FlightGraphStats`
Statistics for monitoring.
```python
class FlightGraphStats:
    flight_id: str
    num_frames: int
    num_factors: int
    num_chunks: int
    num_active_chunks: int
    estimated_memory_mb: float
    last_optimization_time_ms: float
```

## Unit Tests

### Test: delete_flight_graph_success
- Arrange: Create flight graph with factors
- Act: Call delete_flight_graph
- Assert: Returns True, graph removed

### Test: delete_flight_graph_nonexistent
- Arrange: No graph for flight_id
- Act: Call delete_flight_graph
- Assert: Returns False (graceful handling)

### Test: delete_flight_graph_cleans_chunks
- Arrange: Create flight with multiple chunks
- Act: Delete flight graph
- Assert: All chunk subgraphs cleaned up

### Test: flight_isolation_no_cross_contamination
- Arrange: Create flight_1, flight_2
- Act: Add factors to flight_1
- Assert: flight_2 graph unchanged

### Test: concurrent_flight_processing
- Arrange: Create flight_1, flight_2
- Act: Add factors to both concurrently
- Assert: Both maintain independent state

### Test: get_or_create_creates_new
- Arrange: No existing graph
- Act: Call internal _get_or_create_flight_graph
- Assert: New graph created with default state

### Test: get_or_create_returns_existing
- Arrange: Graph exists for flight_id
- Act: Call internal _get_or_create_flight_graph
- Assert: Same graph instance returned

### Test: flight_statistics_accurate
- Arrange: Create flight with known factors
- Act: Get flight statistics
- Assert: Counts match expected

## Integration Tests

### Test: multi_flight_concurrent_processing
1. Create flight_1, flight_2, flight_3 concurrently
2. Add factors to each flight in parallel
3. Optimize each flight independently
4. Verify each flight has correct trajectory
5. Delete flight_2
6. Verify flight_1, flight_3 unaffected

### Test: flight_cleanup_memory_release
1. Create flight with 1000 frames
2. Optimize trajectory
3. Note memory usage
4. Delete flight graph
5. Verify memory released (within tolerance)

### Test: reference_origin_per_flight
1. Create flight_1 with start GPS at point A
2. Create flight_2 with start GPS at point B
3. Add absolute factors to each
4. Verify ENU coordinates relative to respective origins

### Test: chunk_cleanup_on_flight_delete
1. Create flight with 5 chunks
2. Add factors and anchors to chunks
3. Delete flight
4. Verify all chunk subgraphs cleaned up
5. Verify no memory leaks

