use registry::Security;

const APP_REG_PATH: &str = r"Software\HardwareToolkit\";
#[allow(dead_code)]
pub fn get_lib_dir() -> Result<String, anyhow::Error> {
    let reg = registry::Hive::CurrentUser.open(APP_REG_PATH, Security::AllAccess)?;
    let path = reg.value("lib_path")?;
    Ok(path.to_string())
}

#[allow(dead_code)]
pub fn set_lib_dir(path: &str) -> Result<(), anyhow::Error> {
    let path = utfx::U16CString::from_str(path)?;
    let reg = registry::Hive::CurrentUser.create(APP_REG_PATH, Security::AllAccess)?;
    reg.set_value("lib_path", &registry::Data::String(path))?;
    Ok(())
}

#[allow(dead_code)]
pub fn get_odbc_name() -> Result<String, anyhow::Error> {
    let reg = registry::Hive::CurrentUser.open(APP_REG_PATH, Security::AllAccess)?;
    let name = reg.value("odbc_name")?;
    Ok(name.to_string())
}

#[allow(dead_code)]
pub fn set_odbc_name(name: &str) -> Result<(), anyhow::Error> {
    let name = utfx::U16CString::from_str(name)?;
    registry::Hive::CurrentUser
        .create(APP_REG_PATH, Security::AllAccess)?
        .set_value("odbc_name", &registry::Data::String(name))?;
    Ok(())
}

#[allow(dead_code)]
pub fn get_step_dir() -> Result<String, anyhow::Error> {
    let reg = registry::Hive::CurrentUser.open(APP_REG_PATH, Security::AllAccess)?;
    let path = reg.value("step_path")?;
    Ok(path.to_string())
}

#[allow(dead_code)]
pub fn set_step_dir(path: &str) -> Result<(), anyhow::Error> {
    let path = utfx::U16CString::from_str(path)?;
    let reg = registry::Hive::CurrentUser.create(APP_REG_PATH, Security::AllAccess)?;
    reg.set_value("step_path", &registry::Data::String(path))?;
    Ok(())
}

#[allow(dead_code)]
pub fn set_curr_theme(c: u32) -> Result<(), anyhow::Error> {
    let reg = registry::Hive::CurrentUser.create(APP_REG_PATH, Security::AllAccess)?;
    reg.set_value("curr_theme", &registry::Data::U32(c))?;
    Ok(())
}

#[allow(dead_code)]
pub fn get_curr_theme() -> Result<u32, anyhow::Error> {
    let reg = registry::Hive::CurrentUser.open(APP_REG_PATH, Security::AllAccess)?;
    match reg.value("curr_theme")? {
        registry::Data::U32(v) => {
            return Ok(v);
        }
        _ => {
            log::info!("The curr_page is an empty value.");
        }
    }
    Ok(0)
}

#[allow(dead_code)]
pub fn set_curr_page(c: u32) -> Result<(), anyhow::Error> {
    let reg = registry::Hive::CurrentUser.create(APP_REG_PATH, Security::AllAccess)?;
    reg.set_value("curr_page", &registry::Data::U32(c))?;
    Ok(())
}

#[allow(dead_code)]
pub fn get_curr_page() -> Result<u32, anyhow::Error> {
    let reg = registry::Hive::CurrentUser.open(APP_REG_PATH, Security::AllAccess)?;
    match reg.value("curr_page")? {
        registry::Data::U32(v) => {
            return Ok(v);
        }
        _ => {
            log::info!("The curr_page is an empty value.");
        }
    }
    Ok(0)
}

#[allow(dead_code)]
#[cfg(test)]
mod app_settings_test {
    use crate::utils::app_settings::{get_step_dir, set_step_dir};

    #[test]
    fn test_get_set_step_dir() {
        let test_path = "DEADBEAF";
        let ori = get_step_dir();
        assert!(set_step_dir(test_path).is_ok());
        assert!(get_step_dir().is_ok());
        assert_eq!(get_step_dir().unwrap().as_str(), test_path);
        match ori {
            Ok(r) => {
                assert!(set_step_dir(r.as_str()).is_ok());
            }
            Err(e) => {
                println!("FUCK: {e:?}");
            }
        }
    }
}
