/* Historical Difference for commit scope */
use super::{commit_iter::ResolvedCommitsIterator};
use super::history::{FileHistory, HunkInfo};

pub fn missing_searcher(info: &HunkInfo, file_history: &FileHistory) -> Result<(), String> {
    let downstream_commits: Vec<_> = ResolvedCommitsIterator::new(
        &info.downstream_repo
            .walk(b"HEAD")
            .base(info.fork_point.as_deref())
            .line_range(&info.downstream_file, &info.downstream_range)
    )
        .map_while(|item| item.ok())
        .collect();

    // iterate the upstream commits, check if they are in the downstream commits
    let upstream_commits_iter = info.upstream_repo
        .walk(&info.upstream_sha)
        .base(info.fork_point.as_deref())
        .line_range(&info.upstream_file, &info.upstream_range)
        .iter_sha()
        .map_while(|item| item.ok());
    for upstream_commit in upstream_commits_iter {
        if upstream_commit == info.upstream_sha {
            continue;
        }
        if !downstream_commits.iter()
            .any(|(downstream_commit, resolved_sha)|
                resolved_sha.as_ref().map_or(false, |sha| upstream_commit.starts_with(sha)) ||
                upstream_commit.starts_with(downstream_commit)
            )
        {
            info.report_missing_downstream(&upstream_commit)?;
        }
    }

    // iterate the downstream commits, check if they are in the upstream commits
    for (downstream_commit, resolved_sha) in &downstream_commits {
        if !file_history.is_upstream(resolved_sha.as_ref().unwrap_or(&downstream_commit)) {
            info.report_missing_upstream(downstream_commit)?;
        }
    }
    Ok(())
}
