use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;

fn main() {
    let out_dir = env::var("OUT_DIR").expect("Failed to get OUT_DIR env var");

    // -------------------------------------------------------------------------------------
    // setup feedly API secrets
    // -------------------------------------------------------------------------------------
    let feedly_client_id = match env::var("FEEDLY_CLIENT_ID") {
        Ok(client_id) => Some(client_id),
        Err(_) => {
            println!("FEEDLY_CLIENT_ID not defined");
            None
        }
    };

    let feedly_client_secret = match env::var("FEEDLY_CLIENT_SECRET") {
        Ok(client_secret) => Some(client_secret),
        Err(_) => {
            println!("FEEDLY_CLIENT_SECRET not defined");
            None
        }
    };

    let feedly_client_id = match feedly_client_id {
        Some(id) => format!(r#"Some(obfstr::obfstr!("{id}").into())"#),
        None => "None".into(),
    };

    let feedly_client_secret = match feedly_client_secret {
        Some(secret) => format!(r#"Some(obfstr::obfstr!("{secret}").into())"#),
        None => "None".into(),
    };

    let feedly_dest_path = format!("{out_dir}/feedly_secrets.rs");
    let feedly_dest_path = Path::new(&feedly_dest_path);

    let mut f = File::create(feedly_dest_path).expect("Cant create feedly secrets file");

    let feedly_secrets = format!(
        r#"
    #[derive(Debug)]
    pub struct FeedlySecrets {{
        client_id: Option<String>,
        client_secret: Option<String>,
    }}

    impl FeedlySecrets {{
        pub fn new() -> Self {{
            FeedlySecrets {{
                client_id: {feedly_client_id},
                client_secret: {feedly_client_secret},
            }}
        }}

        pub fn id(&self) -> String {{
            self.client_id.clone().expect("feedly should only be available when API secrets were provided")
        }}

        pub fn secret(&self) -> String {{
            self.client_secret.clone().expect("feedly should only be available when API secrets were provided")
        }}

        pub fn valid(&self) -> bool {{
            self.client_id.is_some() && self.client_secret.is_some()
        }}
    }}
    "#
    );
    f.write_all(feedly_secrets.as_bytes()).expect("failed to write feedly secrets.rs");

    // -------------------------------------------------------------------------------------
    // setup password encryption key
    // -------------------------------------------------------------------------------------
    let password_crypt_key = match env::var("PASSWORD_CRYPT_KEY") {
        Ok(pass_crypt_key) => pass_crypt_key,
        Err(_) => {
            println!("PASSWORD_CRYPT_KEY not defined");
            "PASSWORD_CRYPT_KEY_FALLBACK".to_owned()
        }
    };

    let password_dest_path = format!("{out_dir}/password_crypt_key.rs");
    let password_dest_path = Path::new(&password_dest_path);

    let resource_folder = password_dest_path.parent().expect("Can't extract parent folder from path");

    std::fs::create_dir_all(resource_folder).expect("couldn't create resource folder");

    let mut f = File::create(password_dest_path).expect("Cant create password crypt file");

    let password_secrets = format!(
        r#"
    #[derive(Debug)]
    pub struct PasswordCryptKey;

    impl PasswordCryptKey {{
        pub fn get() -> String {{
            obfstr::obfstr!("{password_crypt_key}").into()
        }}
    }}
    "#
    );
    f.write_all(password_secrets.as_bytes()).expect("failed to write password_crypt_key.rs");
}
