use crate::config::Config;
use crate::dialogue::{DialogueStore, refresh_book};
use crate::project::ProjectLayout;
use crate::prose::ProseStore;
use crate::prose::violations::Violation;
use crate::store::Store;
use crate::store::hierarchy::Hierarchy;
use crate::store::node::Node;
use super::Finding;
use super::fast::synthesize;
pub(crate) fn gather(
store: &Store,
layout: &ProjectLayout,
h: &Hierarchy,
cfg: &Config,
book: &Node,
now: &str,
) -> Result<Vec<Finding>, String> {
let root = store.project_root();
let ds = DialogueStore::open(root).map_err(|e| e.to_string())?;
refresh_book(&ds, layout, h, cfg, book, None, now).map_err(|e| e.to_string())?;
let pstore = ProseStore::open(root).map_err(|e| e.to_string())?;
let voices = crate::chorus::voices::character_profiles(&pstore, &ds, cfg, book, None, now)
.map_err(|e| e.to_string())?;
let matrix = crate::chorus::distinct::matrix(
&voices,
cfg.chorus.distinct_threshold,
&cfg.chorus.distinct_ignore_pairs,
);
let drifts: Vec<(String, Vec<Violation>)> = voices
.iter()
.map(|v| (v.name.clone(), crate::chorus::drift::character_drift(v, &cfg.prose.thresholds)))
.filter(|(_, d)| !d.is_empty())
.collect();
let head_hops = crate::chorus::pov::scan_head_hops(layout, h, cfg, book);
let tense = crate::chorus::tense::scan_tense(layout, h, cfg, book);
let register = crate::chorus::register::scan_register(layout, h, cfg, book);
Ok(synthesize(&matrix, &drifts, &head_hops, &tense, ®ister))
}