use glob::glob;
use std::collections::HashMap;
use std::error::Error;
use std::path::Component;

use migration::Migration;

pub fn 
(pattern: &str) -> Result<HashMap<String, Vec<Migration>>, String> {
    let mut migration_files = HashMap::new();
    let entries = glob(pattern).map_err(|err| format!("Failed to read {} due {}", pattern, err))?;

    for entry in entries {
        let path = entry.map_err(|err| {
            format!(
                "Failed to read entry {} in {}",
                err.description(),
                err.path().display()
            )
        })?;

        let folder = path.components().nth(1).ok_or(format!(
            "Could not find keyspace folder name from {}",
            path.display()
        ))?;

        let keyspace = match folder {
            Component::Normal(keyspace) => keyspace
                .to_str()
                .map(|k| k.to_string())
                .ok_or(format!("Couldn't make string out of {:?}", keyspace)),
            _ => Err(format!(
                "There is no keyspace folder in path {}",
                path.display()
            )),
        }?;

        info!("File {:?} in keyspace {:?}", path.display(), keyspace);
        let migration =
            Migration::read_from(&path).map_err(|err| format!("{}: {}", path.display(), err))?;

        migration_files
            .entry(keyspace)
            .or_insert_with(|| vec![])
            .push(migration)
    }

    Ok(migration_files)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn read_migration_files() {
        let read = read_migrations("./migrations/one/*.cql");
        assert!(read.is_ok());

        let migrations_map = read.unwrap();
        assert_eq!(1, migrations_map.len());

        let migrations = migrations_map.get("one").unwrap();
        assert_eq!(2, migrations.len());
    }
}

read_migrations