<commit_before>use ::xflow::xfstruct::*;
use ::xflow::errors::*;

pub struct ValidationError {
    pub code:    i32,
    pub message: String,
    pub paths:   Vec<String>,
}

impl ValidationError {
    /// Constructs a new `ValidationError`
    ///
    /// # Example
    /// ```
    /// use xfdocs::xflow::validation::{ValidationError};
    /// let err = ValidationError::new(1, "sample error".to_string(), Vec::<String>::new());
    /// ```
    pub fn new(code:i32, message:String, paths:Vec<String>) -> ValidationError {
        ValidationError {
            code:    code,
            message: message,
            paths:   paths
        }
    }
}

pub struct Validation {
    pub errors: Vec<ValidationError>,
}

impl Validation {

    /// Constructs a new `Validation`
    ///
    /// # Example
    /// ```
    /// use xfdocs::xflow::validation::{Validation};
    /// let validation = Validation::new();
    /// ```
    pub fn new() -> Validation {
        Validation {
            errors: Vec::<ValidationError>::new()
        }
    }

   pub fn validate(&self, xflow:&XFlowStruct) {
       // let mut x = self.all_edges_have_nodes(xflow);
       // self.errors.append(x);
   }

    pub fn all_edges_have_nodes(xflow:&XFlowStruct) -> Vec<&ValidationError> {
        let mut errors = Vec::<&ValidationError>::new();

        let mut node_ids = xflow.nodes.iter().map({|node|
            node.id
        }).collect::<Vec<i32>>();

        node_ids.sort();
        node_ids.dedup();

        // println!("Got x3 {:?}", node_ids);


//       xflow.edges.iter().map({|edge|
//
//           println!("Got edge {:?}", &edge);
//
//           if !node_ids.contains(edge[0]) {
//               errors.push(ValidationError {
//                   code:    1,
//                   message: format!("Edge {} has no connecting node {:?}", *edge, *edge[0]),
//                   paths:   vec![format!("/edges/{}", *edge)],
//               });
//           };
//
//           if !node_ids.contains(edge[1]) {
//               errors.push(ValidationError {
//                   code:    1,
//                   message: format!("Edge {} has no connecting node {:?}", *edge, *edge[1]),
//                   paths:   vec![format!("/edges/{}", *edge)],
//               });
//           };
//
//       });

       errors
   }
//
//    fn has_one_entry_node(&self, xflow:&XFlowStruct) -> Vec<ValidationError> {
//        let mut errors = Vec::<ValidationError>::new();
//
//        let res = xflow.get_nodes_by("flow", "start");
//        match res.len() {
//            0 => {
//                errors.push(ValidationError {
//                    code:    1,
//                    message: "XFlow has no entry nodes".to_string(),
//                    paths:   vec!["/nodes".to_string()],<commit_msg>Add validation all_edges_have_nodes<commit_after>use ::xflow::xfstruct::*;
use ::xflow::errors::*;

pub struct ValidationError {
    pub code:    i32,
    pub message: String,
    pub paths:   Vec<String>,
}

impl ValidationError {
    /// Constructs a new `ValidationError`
    ///
    /// # Example
    /// ```
    /// use xfdocs::xflow::validation::{ValidationError};
    /// let err = ValidationError::new(1, "sample error".to_string(), Vec::<String>::new());
    /// ```
    pub fn new(code:i32, message:String, paths:Vec<String>) -> ValidationError {
        ValidationError {
            code:    code,
            message: message,
            paths:   paths
        }
    }
}

pub struct Validation {
    pub errors: Vec<ValidationError>,
}

impl Validation {

    /// Constructs a new `Validation`
    ///
    /// # Example
    /// ```
    /// use xfdocs::xflow::validation::{Validation};
    /// let validation = Validation::new();
    /// ```
    pub fn new() -> Validation {
        Validation {
            errors: Vec::<ValidationError>::new()
        }
    }

   pub fn validate(&self, xflow:&XFlowStruct) {
       // let mut x = self.all_edges_have_nodes(xflow);
       // self.errors.append(x);
   }

    pub fn all_edges_have_nodes(xflow:&XFlowStruct) -> Vec<ValidationError> {
        let mut errors = Vec::<ValidationError>::new();

        let mut node_ids = xflow.nodes.iter().map({|node|
            node.id.clone()
        }).collect::<Vec<i32>>();

        node_ids.sort();
        node_ids.dedup();

        for edge in xflow.edges.iter() {

            if !node_ids.contains(&edge.0) {
                errors.push(ValidationError {
                    code:    1,
                    message: format!("Edge {:?} has no connecting node {:?}", edge, edge.0),
                    paths:   vec![format!("/edges/{:?}", edge)],
                });
            };

            if !node_ids.contains(&edge.1) {
                errors.push(ValidationError {
                    code:    1,
                    message: format!("Edge {:?} has no connecting node {:?}", edge, edge.1),
                    paths:   vec![format!("/edges/{:?}", edge)],
                });
            };
        }

       errors
   }
//
//    fn has_one_entry_node(&self, xflow:&XFlowStruct) -> Vec<ValidationError> {
//        let mut errors = Vec::<ValidationError>::new();
//
//        let res = xflow.get_nodes_by("flow", "start");
//        match res.len() {
//            0 => {
//                errors.push(ValidationError {
//                    code:    1,
//                    message: "XFlow has no entry nodes".to_string(),
//                    paths:   vec!["/nodes".to_string()],
{'fraction_non_alphanumeric': 0.17697500456121146, 'fraction_numerical': 0.005655902207626346, 'mean_word_length': 1.6965076242006887, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7114773', 'n_tokens_mistral': 1655, 'n_tokens_neox': 1592, 'n_words': 318}