use std::sync::Arc;
use crate::filters::{CanonicalTs, timestamp_to_canonical};
use crate::ingestion::{FileReader, MergedEntry};
use crate::parser::LogFormatParser;
use crate::ui::tab_state::year_map::YearMap;
pub struct MergedState {
pub source_tab_indices: Vec<usize>,
pub source_parsers: Vec<Option<Arc<dyn LogFormatParser>>>,
pub source_labels: Vec<String>,
pub source_line_counts: Vec<usize>,
pub label_col_width: usize,
pub stopped: bool,
}
pub fn build_merged_index(
sources: &[FileReader],
parsers: &[Option<Arc<dyn LogFormatParser>>],
year_maps: &[Option<Arc<YearMap>>],
continuation_maps: &[Option<Arc<Vec<usize>>>],
) -> Vec<MergedEntry> {
let mut entries = Vec::new();
for (source_idx, source) in sources.iter().enumerate() {
let parser = parsers[source_idx].as_deref();
let year_map = year_maps[source_idx].as_deref();
let cmap = continuation_maps[source_idx].as_deref();
append_source_entries(&mut entries, source, parser, year_map, cmap, source_idx, 0);
}
entries.sort_unstable_by_key(|a| a.sort_key);
entries
}
pub fn extend_merged_index(
entries: &mut Vec<MergedEntry>,
source: &FileReader,
parser: Option<&dyn LogFormatParser>,
year_map: Option<&YearMap>,
continuation_map: Option<&Vec<usize>>,
source_idx: usize,
from_line: usize,
) {
append_source_entries(
entries,
source,
parser,
year_map,
continuation_map,
source_idx,
from_line,
);
entries.sort_unstable_by_key(|a| a.sort_key);
}
fn append_source_entries(
entries: &mut Vec<MergedEntry>,
source: &FileReader,
parser: Option<&dyn LogFormatParser>,
year_map: Option<&YearMap>,
continuation_map: Option<&Vec<usize>>,
source_idx: usize,
from_line: usize,
) {
let count = source.line_count();
let mut current_key: Option<CanonicalTs> = None;
for line_idx in from_line..count {
let line = source.get_line(line_idx);
let ts = parser.and_then(|p| p.parse_timestamp(line));
if let Some(ts_str) = ts {
let year_override = year_map.map(|ym| ym.year_for_line(line_idx));
if let Some(key) = timestamp_to_canonical(ts_str, year_override) {
current_key = Some(key);
entries.push(MergedEntry {
sort_key: key,
source_idx,
line_idx,
});
continue;
}
}
let is_continuation = continuation_map
.map(|cmap| cmap.get(line_idx).copied().unwrap_or(line_idx) != line_idx)
.unwrap_or(false);
if is_continuation && let Some(key) = current_key {
entries.push(MergedEntry {
sort_key: key,
source_idx,
line_idx,
});
}
}
}