zc2 0.0.27

P2P compute broker with credit-based billing, WAL, and broker mesh support
use crate::exec;

use std::path::Path;

use std::env;
use std::str;

pub static CONFIG_FILE: &str = "/opt/zakuro/etc/profile.d/zk0.sh";
pub static CONFIG_DIR: &str = "/opt/zakuro/etc/profile.d";
use std::collections::HashSet;
pub fn eval(s1: &str) -> String {
    evaluate_expr(s1)
}
use crate::common::print_debug;

// fn skip_first_char_if_slash(output: &str) -> Result<String, String> {
//     // Check if the string is long enough to slice
//     if !output.is_empty() && output.starts_with('/') {
//         let result: String = output[1..].to_string();
//         return Ok(result);
//     } else if !output.is_empty() {
//         return Ok(output.to_string());
//     }
//     Err(String::from("String is empty!"))
// }

pub fn evaluate_expr(s1: &str) -> String {
    let mut output: String = String::from("");
    if !s1.starts_with("'") {
        // Extract path x:x
        for pathx in s1.split(':') {
            // For each x split by /
            let splits: Vec<&str> = pathx.split("/").collect();
            let condition: bool = splits.len() > 1;
            for varpath in splits {
                if let Some('$') = varpath.chars().next() {
                    let _varpath = &varpath[1..];
                    if let Ok(s) = env::var(_varpath) {
                        // println!("found: {:?}",&s);
                        env::set_var(_varpath, &s);
                        output.push_str(&s.to_string());
                    } else {
                        // println!("(var not found) ${:?}", _varpath);
                        output.push_str((&varpath).as_ref());
                    }
                } else if condition {
                    output.push_str(&format!("/{}", varpath));
                } else {
                    output.push_str((&varpath).as_ref());
                }
            }
            output.push(':');
        }
        if output.ends_with(':') {
            output = output[..output.len() - 1].to_string();
        }
        // match skip_first_char_if_slash(output.clone()){
        //     Ok(res) => {
        //         output = res;
        //     }
        //     Err(e) => {
        //         eprintln!("{}", e);
        //     }
        // }

        // output = skip_first_char_if_slash(&output).unwrap_or_else(|e| {
        //     eprintln!("{}", e);
        //     output.clone()  // Return the original output in case of an error
        // });

        // if (&output[1..]).to_string().starts_with('/') {
        //     output = (&output[1..]).to_string();
        // }
        output = output.replace("//", "/");
        // println!("{:?}",output);
        let string_list: Vec<&str> = output.split(":").collect();
        // Create a HashSet to store unique values
        let unique_values: HashSet<_> = string_list.into_iter().collect();
        // Convert the HashSet back to a Vec if needed
        let unique_list: Vec<_> = unique_values.into_iter().collect();
        // println!("{:?}", unique_list);
        output = unique_list.join(":");
    } else {
        output = String::from(s1);
    }

    output
}

pub fn update() {
    if !Path::new(CONFIG_FILE).exists() {
        for command in [
            &format!("sudo mkdir -p {}", CONFIG_DIR),
            &format!("sudo chown -R $USER {}", CONFIG_DIR),
            &format!("wget -q 'http://get.zakuro-ai.com/env' -O {}", CONFIG_FILE),
        ] {
            exec::tty(command);
        }
    }

    // Read the content of the shell script
    let script_content = match std::fs::read_to_string(CONFIG_FILE) {
        Ok(content) => content,
        Err(e) => {
            eprintln!("Error reading script: {}", e);
            return;
        }
    };

    // Parse the script content to extract variable assignments
    for line in script_content.lines() {
        // Check if the line is a variable assignment
        if let Some((key, _value)) = line.split_once('=') {
            if env::var(key).is_err() {
                let value = evaluate_expr(_value);
                // let value = _value;
                // Only print in debug mode
                print_debug(&format!("{}={}", key, value));
                env::set_var(key, value);
            }
        }
    }
}