use super::DbOrf;
use std::collections::HashMap;
use std::path::Path;
pub fn ingest_isfinder(is_faa: &Path, is_csv: &Path) -> Result<Vec<DbOrf>, String> {
let fam = parse_is_csv(is_csv)?; let data = std::fs::read(is_faa).map_err(|e| format!("read {}: {e}", is_faa.display()))?;
let text = String::from_utf8_lossy(&data);
let mut out: Vec<DbOrf> = Vec::new();
let mut keep = false;
let mut id = String::new();
let mut family = String::new();
let mut seq: Vec<u8> = Vec::new();
for line in text.lines() {
if let Some(hdr) = line.strip_prefix('>') {
if keep && !seq.is_empty() {
out.push(DbOrf {
id: std::mem::take(&mut id),
family: std::mem::take(&mut family),
source: "ISfinder",
seq: std::mem::take(&mut seq),
});
}
seq.clear();
let parts: Vec<&str> = hdr.split("~~~").collect();
let first_tok = parts
.first()
.and_then(|s| s.split_whitespace().next())
.unwrap_or("");
let func = parts.get(2).map(|s| s.trim()).unwrap_or("");
keep = func == "Transposase";
let descr = parts
.get(1)
.map(|s| s.trim())
.filter(|s| !s.is_empty())
.unwrap_or(first_tok);
id = descr.to_string();
let isname = first_tok.strip_prefix("html.2020//").unwrap_or(first_tok);
family = fam.get(isname).cloned().unwrap_or_else(|| "unknown".to_string());
} else if keep {
seq.extend(line.trim().bytes().filter(|&b| b != b'\r'));
}
}
if keep && !seq.is_empty() {
out.push(DbOrf { id, family, source: "ISfinder", seq });
}
Ok(out)
}
fn parse_is_csv(path: &Path) -> Result<HashMap<String, String>, String> {
let data = std::fs::read_to_string(path).map_err(|e| format!("read {}: {e}", path.display()))?;
let mut map = HashMap::new();
for (i, line) in data.lines().enumerate() {
if i == 0 || line.trim().is_empty() {
continue; }
let cols: Vec<&str> = line.splitn(4, ',').collect();
if cols.len() >= 3 {
let name = cols[1].trim();
let family = cols[2].trim();
if !name.is_empty() && !family.is_empty() {
map.insert(name.to_string(), family.to_string());
}
}
}
Ok(map)
}