use super::{super::implementation::*, problem::*, weakly::*};

use std::cmp::*;

/// Iterate unique problems.
///
/// Equality is tested for using the first [CauseEquality](super::super::cause::CauseEquality) or
/// [CauseComparison](super::super::cause::CauseComparison) found in each problem.
///
/// See: [WeaklyComparableProblem].
pub fn iter_unique_problems<'problems, ProblemsT>(
    problems: ProblemsT,
) -> impl Iterator<Item = Problem>
where
    ProblemsT: IntoIterator<Item = Problem>,
{
    let mut problems: Vector<_> = problems.into_iter().map(WeaklyComparableProblem).collect();
    dedup(&mut problems);
    problems.into_iter().map(|problem| problem.0)
}

/// Iterate unique problem references.
///
/// Equality is tested for using the first [CauseEquality](super::super::cause::CauseEquality) or
/// [CauseComparison](super::super::cause::CauseComparison) found in each problem.
///
/// See: [WeaklyComparableProblemRef].
pub fn iter_unique_problem_refs<'problems, ProblemsT>(
    problems: ProblemsT,
) -> impl Iterator<Item = &'problems Problem>
where
    ProblemsT: IntoIterator<Item = &'problems Problem>,
{
    let mut problems: Vector<_> = problems
        .into_iter()
        .map(WeaklyComparableProblemRef)
        .collect();
    dedup(&mut problems);
    problems.into_iter().map(|problem| problem.0)
}

// Utils

fn dedup<ItemT>(vector: &mut Vector<ItemT>)
where
    ItemT: PartialEq,
{
    let length = vector.len();
    if length > 1 {
        for index in (1..length).rev() {
            if vector[0..index].contains(&vector[index]) {
                vector.remove(index);
            }
        }
    }
}
