use serde_json::Value;
use crate::relationships::{corpus_items, relationships_from_corpus, CorpusItem, Relationship};
use crate::resolve::{entry_from_item, field_tokens_of, is_live_decision, FieldTokens, IndexEntry};
use crate::retrieve::{scope_rows_from_items, ScopeRow};
pub const SCHEMA_VERSION: &str = "3";
pub(crate) const DECISION_TYPE: &str = "decision";
pub struct DerivedIndex {
pub index_entries: Vec<IndexEntry>,
pub field_tokens: Vec<FieldTokens>,
pub relationships: Vec<Relationship>,
pub live_decision_paths: Vec<String>,
pub portfolio_summary: Value,
pub scope_rows: Vec<ScopeRow>,
}
pub fn build_derived_index_from_items(
directory: &str,
items: &[CorpusItem],
recursive: bool,
) -> DerivedIndex {
let relationships = relationships_from_corpus(items);
let mut inbound: std::collections::HashMap<&str, i64> = std::collections::HashMap::new();
for rel in &relationships {
if let Some(resolved) = &rel.resolved_path {
*inbound.entry(resolved.as_str()).or_insert(0) += 1;
}
}
let index_entries: Vec<IndexEntry> = items
.iter()
.map(|item| {
entry_from_item(item, inbound.get(item.path.as_str()).copied().unwrap_or(0))
})
.collect();
let field_tokens: Vec<FieldTokens> = index_entries.iter().map(field_tokens_of).collect();
let live_decision_paths: Vec<String> = items
.iter()
.filter(|item| {
item.spec.map(|s| s.name == DECISION_TYPE).unwrap_or(false)
&& is_live_decision(&item.artifact)
})
.map(|item| item.path.clone())
.collect();
let summary = crate::portfolio::portfolio_from_corpus(directory, items, recursive);
DerivedIndex {
index_entries,
field_tokens,
relationships,
live_decision_paths,
portfolio_summary: crate::output::portfolio_summary_value(&summary),
scope_rows: scope_rows_from_items(items),
}
}
pub fn build_derived_index(directory: &str, recursive: bool) -> DerivedIndex {
let items = corpus_items(directory, recursive);
build_derived_index_from_items(directory, &items, recursive)
}