use crate::domain::Domain;
use std::fs::File;
use std::io::{self, BufRead};
use std::path::PathBuf;

/// Load and parse a domain configuration file into `Domain` entries.
///
/// Each non-empty, non-comment line is interpreted as a domain identifier.
/// Lines starting with `#` or `//` and blank lines are ignored. Each line is
/// converted to a `Domain` using [`Domain::new`]. Invalid URLs are skipped with
/// a warning to stderr.
///
/// Returns `None` if the file cannot be opened; otherwise returns `Some(Vec)`
/// which may be empty if the file has no valid domains.
///
/// Expected file format example:
/// ```text
/// # Comment lines start with '#'
/// // Or with '//'
/// example.com
/// https://example.org
/// 
/// # Blank lines are ignored
/// 
/// invalid url here  // will be skipped with a warning
/// ```
///
/// Example (no_run):
/// ```no_run
/// use std::fs::write;
/// use std::path::PathBuf;
/// use domain_checker_lite::get_config;
///
/// // Prepare a simple config file
/// let path = PathBuf::from("/tmp/domains.txt");
/// write(&path, b"example.com\n# comment\nhttps://example.org\n").unwrap();
///
/// // Load the domains
/// let domains = get_config(path).unwrap();
/// assert!(domains.len() >= 2);
/// ```
pub fn get_config(domain_file: PathBuf) -> Option<Vec<Domain>> {
    let mut out: Vec<Domain> = Vec::new();
    let file: File;

    // Tries to open the domain file
    match File::open(&domain_file) {
        Ok(f) => file = f,
        Err(_) => {
            let path_string = domain_file.to_string_lossy();
            eprintln!("Error opening {path_string}");
            return None
        }
    }

    let lines = io::BufReader::new(file).lines();

    // Creates new Domain structs from each line in hte config
    for line in lines {
        match line {
            Ok(l) => {
                if 
                    l.trim().starts_with("#") || 
                    l.trim().starts_with("//") || 
                    l.trim().is_empty()
                {
                    continue
                }

                match Domain::new(& l.trim()) {
                    Ok(d) => out.push(d),
                    Err(_) => eprint!("Unable to parse url: {l}")
                };
            },
            Err(_) => eprintln!("Unable to read line")
        }
    }
    
    Some(out)
}