use crate::Graph;
use std::collections::HashSet;

pub fn binary_edge(graph: &Graph, k: u16, v: HashSet<u16>) -> Option<HashSet<u16>> {
    let edge = match graph.get_edge_filtered(&v) {
        Some(edge) => edge,
        None => return Some(v),
    };

    if k == 0 {
        return None;
    }

    let mut v1 = v.clone();
    v1.insert(edge.0);
    match binary_edge(graph, k - 1, v1) {
        Some(s) => Some(s),
        None => {
            let mut v2 = v;
            v2.insert(edge.1);
            binary_edge(graph, k - 1, v2)
        }
    }
}

pub fn binary_vertex(graph: &Graph, k: u16, v: HashSet<u16>) -> Option<HashSet<u16>> {
    let vertex = match graph.get_vertex_filtered_with_degree_greater(&v, 2) {
        Some(vertex) => vertex,
        None => {
            return {
                let mut v3 = v;
                let mut c = 0;
                while let Some(vertex) = graph.get_vertex_filtered_with_degree_greater(&v3, 1) {
                    v3.insert(vertex);
                    c += 1;
                }

                if c <= k {
                    Some(v3)
                } else {
                    None
                }
            }
        }
    };

    if k == 0 {
        return None;
    }

    let mut v1 = v.clone();
    v1.insert(vertex);
    match binary_vertex(graph, k - 1, v1) {
        Some(s) => Some(s),
        None => {
            let mut v2 = v;
            let mut c = 0;
            for o in graph.get_edges(vertex) {
                if !v2.contains(&o) {
                    c += 1;
                    v2.insert(o);
                }
            }
            if c <= k {
                binary_vertex(graph, k - c, v2)
            } else {
                None
            }
        }
    }
}
