use mop_structs::{matrix::dr_matrix::DrMatrix, prelude::*};

use mop_common::quickcheck::quickcheck;

quickcheck! {

fn dr_matrix_row_iter_next(
    dm: DrMatrix<Vec<i32>>
) -> bool {
    dm.row_iter().enumerate().all(|(row_idx, row)| row == dm.row(row_idx))
}

fn dr_matrix_row_iter_next_back(
    dm: DrMatrix<Vec<i32>>
) -> bool {
    let mut i = dm.row_iter();
    let mut idx = dm.rows();
    while let Some(row) = i.next_back() {
        idx -= 1;
        if row != dm.row(idx) {
            return false;
        }
    }
    true
}

fn dr_matrix_row_iter_split_at(
    dm: DrMatrix<Vec<i32>>
) -> bool {
    let split_in = if dm.rows() > 3 { 3 } else { dm.rows() };
    let (first_half, second_half) = dm.row_iter().split_at(split_in);
    let is_first_ok = first_half.enumerate().all(|(row_idx, row)| {
        row == dm.row(row_idx)
    });
    let is_second_ok = second_half.enumerate().all(|(row_idx, row)| {
        row == dm.row(row_idx + split_in)
    });
    is_first_ok && is_second_ok
}

#[cfg(feature = "parallelization")]
fn dr_matrix_row_par_iter(
    dm: DrMatrix<Vec<i32>>
) -> bool {
    dm.row_par_iter().enumerate().all(|(row_idx, row)| row == dm.row(row_idx))
}

}
