use env::Environment;

use crate::syntax::parse::{PipelineElement, PipelineExpression};

pub mod env;
pub mod eval;

pub struct ExpandedPipelineElement {
    pub words: Vec<String>,
    pub envs: Vec<(String, String)>,
}

pub struct ExpandedPipeline {
    pub elements: Vec<ExpandedPipelineElement>,
}

impl ExpandedPipelineElement {
    pub fn from_syntax(env: &Environment, element: &PipelineElement) -> Self {
        // TODO redirects
        let mut words: Vec<_> = element
            .words
            .iter()
            .flat_map(|word| env.expand(word))
            .collect();
        let mut envs = vec![];

        words.retain(|word| {
            if let Some((key, value)) = word.split_once('=')
                && !key.ends_with(' ')
                && !value.starts_with(' ')
            {
                envs.push((key.to_owned(), value.to_owned()));
                false
            } else {
                true
            }
        });

        Self { words, envs }
    }
}

impl ExpandedPipeline {
    pub fn from_syntax(env: &Environment, pipeline: &PipelineExpression) -> Self {
        let elements = pipeline
            .elements
            .iter()
            .map(|e| ExpandedPipelineElement::from_syntax(env, e))
            .collect();
        Self { elements }
    }
}
