use crate::{get_compose_filename, ComposeYaml, Formats, Verbosity};
use colored::Colorize;
use regex::Regex;
use serde_yaml::Mapping;
use std::vec::IntoIter;
use std::{fs, process};
pub fn unwrap_filter_tag(filter: Option<&str>) -> Option<&str> {
    filter.as_ref().map(|f| {
        if let Some(val) = f.strip_prefix("tag=") {
            val
        } else {
            eprintln!(
                "{}: wrong filter '{}', only '{}' filter supported",
                "ERROR".red(),
                f.yellow(),
                "tag=".yellow()
            );
            process::exit(2);
        }
    })
}
pub fn unwrap_filter_regex(filter: Option<&str>) -> Option<(Regex, bool)> {
    filter.as_ref().map(|f| {
        if let Some(val) = f.strip_prefix("regex=") {
            let regex = Regex::new(val).unwrap_or_else(|e| {
                invalid_regex_exit(e, val);
            });
            return (regex, true);
        }
        if let Some(val) = f.strip_prefix("regex!=") {
            let regex = Regex::new(val).unwrap_or_else(|e| {
                invalid_regex_exit(e, val);
            });
            return (regex, false);
        }
        eprintln!(
            "{}: wrong filter '{}', only '{}' or '{}' filters are supported",
            "ERROR".red(),
            f.yellow(),
            "regex=".yellow(),
            "regex!=".yellow()
        );
        process::exit(2);
    })
}
fn invalid_regex_exit(e: regex::Error, val: &str) -> ! {
    eprintln!(
        "{}: invalid regex expression '{}' in filter - {}",
        "ERROR".red(),
        val.yellow(),
        e
    );
    process::exit(2);
}
pub fn print_names(iter: IntoIter<&str>, pretty: Formats) {
    match pretty {
        Formats::Full => iter.for_each(|service| println!("{}", service)),
        Formats::Oneline => println!("{}", iter.collect::<Vec<&str>>().join(" ")),
    }
}
pub fn get_service<'a>(compose: &'a ComposeYaml, service_name: &str) -> &'a Mapping {
    let service = compose.get_service(service_name);
    match service {
        None => {
            eprintln!("{}: No such service found: {}", "ERROR".red(), service_name);
            process::exit(16);
        }
        Some(serv) => serv,
    }
}
pub fn get_yml_content(filename: Option<&str>, verbosity: Verbosity) -> String {
    let filename = get_compose_filename(filename, verbosity).unwrap_or_else(|err| {
        eprintln!("{}: {}", "ERROR".red(), err);
        if err.contains("no such file or directory") {
            process::exit(14);
        }
        process::exit(10);
    });
    fs::read_to_string(filename).unwrap_or_else(|err| {
        eprintln!("{}: reading compose file: {}", "ERROR".red(), err);
        process::exit(11);
    })
}