use super::{TopologyModel, WorkerStation};
use crate::console::error::ConsoleError;
use crate::console::records::{
Connection, Device, DeviceBox, DeviceKind, Link, Station, StationKind, StationState,
TopologyDocument,
};
use crate::console::wall::WallBase;
use std::collections::{BTreeMap, BTreeSet};
impl TopologyModel {
#[must_use]
pub fn document(&self, wall: &WallBase) -> (TopologyDocument, Option<ConsoleError>) {
let this = &self.this.id;
let (started, fault) = match wall.unix_ms_of(self.this.started) {
Ok(started) => (Some(started), None),
Err(error) => (None, Some(error)),
};
let mut devices = vec![Device {
id: this.clone(),
name: this.clone(),
kind: DeviceKind::Device,
liminal: Some(self.this.liminal.clone()),
started,
started_fault: fault.as_ref().map(ToString::to_string),
parent: self.parent.clone(),
zone: Some(DeviceBox::THIS),
}];
let peers: BTreeSet<_> = self
.peers
.iter()
.chain(
self.links
.values()
.flat_map(|link| std::iter::once(&link.name).chain(link.relayed.iter())),
)
.collect();
devices.extend(peers.into_iter().map(|peer| Device {
id: peer.clone(),
name: peer.clone(),
kind: DeviceKind::Device,
liminal: None,
started: None,
started_fault: None,
parent: None,
zone: None,
}));
let depot = self.this.depot.then(|| self.depot_id());
let mut stations: BTreeMap<&String, (StationKind, Option<&WorkerStation>)> = self
.workers
.values()
.filter(|worker| self.reserved(&worker.identity).is_none())
.map(|worker| (&worker.identity, (StationKind::Worker, Some(worker))))
.collect();
stations.extend(
self.stations
.iter()
.filter(|subject| self.reserved(subject).is_none())
.map(|subject| (subject, (StationKind::Service, None))),
);
stations.extend(depot.iter().map(|id| (id, (StationKind::Depot, None))));
stations.insert(this, (StationKind::Exchange, None));
let document = TopologyDocument::new(
self.rev,
this.clone(),
devices,
stations
.into_iter()
.map(|(subject, (kind, worker))| Station {
id: subject.clone(),
name: subject.clone(),
device: this.clone(),
kind,
state: StationState::Live,
subjects: worker.map(|worker| worker.subjects.clone()),
activities: worker.map(|worker| worker.activities.clone()),
})
.collect(),
self.all_lines(),
self.peers
.iter()
.map(|peer| Link::to_peer(this, peer))
.chain(self.links.values().cloned())
.collect(),
self.connections
.iter()
.map(|(id, (mount, participant))| Connection {
id: id.to_string(),
mount: *mount,
participant: participant.clone(),
})
.collect(),
);
(document, fault)
}
}