use std::{
collections::{HashMap, HashSet},
fs,
};
use std::path::Path;
use super::{
get_base_name::get_base_name,
types::{AlertFileStructure, AlertType, FileTypes, Folder, ItemType},
};
pub fn validate_missing_items(
path: &str,
folders: Option<&Vec<Folder>>,
missing_items: &mut Vec<AlertFileStructure>,
required_extensions: &Vec<&str>,
list_of_files_found: &mut HashMap<String, String>,
) {
let base_path = Path::new(path);
if let Some(folders) = folders {
for folder in folders {
let folder_names = &folder.names;
let mut folder_exists = false;
for folder_name in folder_names {
let folder_path = base_path.join(folder_name);
if folder_path.exists() && folder_path.is_dir() {
folder_exists = true;
if let Some(files) = &folder.files {
validate_files(
&folder_path,
files,
missing_items,
required_extensions.clone(),
folder.id.as_ref().unwrap_or(&"".to_string()),
list_of_files_found,
);
}
if let Some(subfolders) = &folder.folders {
validate_missing_items(
folder_path.to_str().unwrap(),
Some(subfolders),
missing_items,
required_extensions,
list_of_files_found,
);
}
break; }
}
if !folder_exists {
if folder.required {
missing_items.push(AlertFileStructure {
path: base_path
.join(&folder_names[0])
.to_string_lossy()
.to_string(),
item_type: ItemType::Folder,
alert_type: AlertType::MissingItem,
});
continue;
}
missing_items.push(AlertFileStructure {
path: base_path
.join(&folder_names[0])
.to_string_lossy()
.to_string(),
item_type: ItemType::Folder,
alert_type: AlertType::Warning,
});
}
}
}
}
fn validate_files(
folder_path: &Path,
files: &Vec<FileTypes>,
missing_items: &mut Vec<AlertFileStructure>,
required_extensions: Vec<&str>,
id_folder: &String,
list_of_files_found: &mut HashMap<String, String>,
) {
let dir_entries: HashSet<String> = fs::read_dir(folder_path)
.unwrap()
.filter_map(|entry| {
let entry = entry.unwrap();
if entry.path().is_file() {
Some(entry.file_name().to_string_lossy().to_string())
} else {
None
}
})
.collect();
for file in files {
let mut extensions_missing: Vec<(&str, bool)> = vec![];
let file_names = &file.names;
for ext in required_extensions.iter() {
let mut file_name_match: (String, String) = (String::new(), String::new());
let mut full_file_name: String = "".to_string();
let exist_full_name_file = file_names.iter().any(|file_name| {
full_file_name = format!("{}.{}", file_name, ext);
let result = dir_entries.contains(&full_file_name);
if result {
file_name_match.0 = file_name.to_owned();
file_name_match.1 = file.id.clone().unwrap_or_default();
}
result
});
if !exist_full_name_file {
extensions_missing.push((&ext, if file.required { true } else { false }));
} else {
list_of_files_found.insert(
format!("{}-{}", id_folder, file_name_match.1),
format!(
"{}/{}",
folder_path.to_string_lossy(),
get_base_name(file_name_match.0.as_str())
),
);
}
}
if extensions_missing.len() > 0 {
for extension_missing in extensions_missing {
missing_items.push(AlertFileStructure {
path: folder_path
.join(format!("{}.{}", file_names[0], extension_missing.0))
.to_string_lossy()
.to_string(),
item_type: ItemType::File,
alert_type: if extension_missing.1 {
AlertType::MissingItem
} else {
AlertType::Warning
},
});
}
}
}
}