// Std
use std::io::Write;

// Internal
use app::parser::Parser;
use INTERNAL_ERROR_MSG;

pub struct ElvishGen<'a, 'b>
where
    'a: 'b,
{
    p: &'b Parser<'a, 'b>,
}

impl<'a, 'b> ElvishGen<'a, 'b> {
    pub fn new(p: &'b Parser<'a, 'b>) -> Self {
        ElvishGen { p: p }
    }

    pub fn generate_to<W: Write>(&self, buf: &mut W) {
        let bin_name = self.p.meta.bin_name.as_ref().unwrap();

        let mut names = vec![];
        let subcommands_cases = generate_inner(self.p, "", &mut names);

        let result = format!(
            r#"
edit:completion:arg-completer[{bin_name}] = [@words]{{
    fn spaces [n]{{
        repeat $n ' ' | joins ''
    }}
    fn cand [text desc]{{
        edit:complex-candidate $text &display-suffix=' '(spaces (- 14 (wcswidth $text)))$desc
    }}
    command = '{bin_name}'
    for word $words[1:-1] {{
        if (has-prefix $word '-') {{
            break
        }}
        command = $command';'$word
    }}
    completions = [{subcommands_cases}
    ]
    $completions[$command]
}}
"#,
            bin_name = bin_name,
            subcommands_cases = subcommands_cases
        );

        w!(buf, result.as_bytes());
    }
}

// Escape string inside single quotes
fn escape_string(string: &str) -> String {
    string.replace("'", "''")
}

fn get_tooltip<T: ToString>(help: Option<&str>, data: T) -> String {
    match help {
        Some(help) => escape_string(help),
        _ => data.to_string(),
    }
}

fn generate_inner<'a, 'b, 'p>(
    p: &'p Parser<'a, 'b>,
    previous_command_name: &str,
    names: &mut Vec<&'p str>,
) -> String {
    debugln!("ElvishGen::generate_inner;");
    let command_name = if previous_command_name.is_empty() {
        p.meta.bin_name.as_ref().expect(INTERNAL_ERROR_MSG).clone()
    } else {
        format!("{};{}", previous_command_name, &p.meta.name)
    };

    let mut completions = String::new();
    let preamble = String::from("\n            cand ");

    for option in p.opts() {
        if let Some(data) = option.s.short {
            let tooltip = get_tooltip(option.b.help, data);
            completions.push_str(&preamble);
            completions.push_str(format!("-{} '{}'", data, tooltip).as_str());
        }
        if let Some(data) = option.s.long {
            let tooltip = get_tooltip(option.b.help, data);
            completions.push_str(&preamble);
            completions.push_str(format!("--{} '{}'", data, tooltip).as_str());
        }
    }

    for flag in p.flags() {
        if let Some(data) = flag.s.short {
            let tooltip = get_tooltip(flag.b.help, data);
            completions.push_str(&preamble);
            completions.push_str(format!("-{} '{}'", data, tooltip).as_str());
        }
        if let Some(data) = flag.s.long {
            let tooltip = get_tooltip(flag.b.help, data);
            completions.push_str(&preamble);
            completions.push_str(format!("--{} '{}'", data, tooltip).as_str());
        }
    }

    for subcommand in &p.subcommands {
        let data = &subcommand.p.meta.name;
        let tooltip = get_tooltip(subcommand.p.meta.about, data);
        completions.push_str(&preamble);
        completions.push_str(format!("{} '{}'", data, tooltip).as_str());
    }

    let mut subcommands_cases = format!(
        r"
        &'{}'= {{{}
        }}",
        &command_name, completions
    );

    for subcommand in &p.subcommands {
        let subcommand_subcommands_cases = generate_inner(&subcommand.p, &command_name, names);
        subcommands_cases.push_str(&subcommand_subcommands_cases);
    }

    subcommands_cases
}
