use std::sync::Arc;

use multi_threading::threadpool::Threadpool;

struct PermutationThreading {
    pool: Arc<Threadpool>,
}

impl PermutationThreading {
    fn new() -> PermutationThreading {
        PermutationThreading { pool: Arc::new(Threadpool::new(20)) }
    }

    fn list_all_permutation_util_threading(
        &self,
        n: usize,
        visited: Vec<bool>,
        arr: Arc<Vec<i32>>,
        per: Vec<i32>,
    ) {
        if per.len() == n {
            println!("{:?}", per);
            return;
        }
        for index in 0..n {
            if visited[index] == false {
                let mut per_ = per.clone();
                let mut visited_ = visited.clone();
                let arr_ = Arc::clone(&arr);
                per_.push(arr[index]);
                visited_[index] = true;
                let self_ref = PermutationThreading{
                    pool:Arc::clone(&self.pool),
                };
                let close = move || {
                    self_ref.list_all_permutation_util_threading(n, visited_, arr_, per_);
                };
                self.pool.execute(Box::new(close));
            }
        }
    }
}
fn main() {
    let per = vec![];
    let visited = vec![false; 5];

    let n = 5;
    let arr = Arc::new(vec![1, 2, 3, 4, 5]);
    let permutaion = PermutationThreading::new();
    permutaion.list_all_permutation_util_threading(n, visited, arr, per);
}