// Std
#[allow(deprecated, unused_imports)]
use std::ascii::AsciiExt;
use std::io::Write;

// Internal
use app::parser::Parser;
use app::App;
use args::{AnyArg, ArgSettings};
use completions;
use INTERNAL_ERROR_MSG;

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

impl<'a, 'b> ZshGen<'a, 'b> {
    pub fn new(p: &'b Parser<'a, 'b>) -> Self {
        debugln!("ZshGen::new;");
        ZshGen { p: p }
    }

    pub fn generate_to<W: Write>(&self, buf: &mut W) {
        debugln!("ZshGen::generate_to;");
        w!(
            buf,
            format!(
                "\
#compdef {name}

autoload -U is-at-least

_{name}() {{
    typeset -A opt_args
    typeset -a _arguments_options
    local ret=1

    if is-at-least 5.2; then
        _arguments_options=(-s -S -C)
    else
        _arguments_options=(-s -C)
    fi

    local context curcontext=\"$curcontext\" state line
    {initial_args}
    {subcommands}
}}

{subcommand_details}

_{name} \"$@\"",
                name = self.p.meta.bin_name.as_ref().unwrap(),
                initial_args = get_args_of(self.p),
                subcommands = get_subcommands_of(self.p),
                subcommand_details = subcommand_details(self.p)
            )
            .as_bytes()
        );
    }
}

// Displays the commands of a subcommand
// (( $+functions[_[bin_name_underscore]_commands] )) ||
// _[bin_name_underscore]_commands() {
// 	local commands; commands=(
// 		'[arg_name]:[arg_help]'
// 	)
// 	_describe -t commands '[bin_name] commands' commands "$@"
//
// Where the following variables are present:
//    [bin_name_underscore]: The full space delineated bin_name, where spaces have been replaced by
//                           underscore characters
//    [arg_name]: The name of the subcommand
//    [arg_help]: The help message of the subcommand
//    [bin_name]: The full space delineated bin_name
//
// Here's a snippet from rustup:
//
// (( $+functions[_rustup_commands] )) ||
// _rustup_commands() {
// 	local commands; commands=(
// 		'show:Show the active and installed toolchains'
//      'update:Update Rust toolchains'
//      # ... snip for brevity
//      'help:Prints this message or the help of the given subcommand(s)'
// 	)
// 	_describe -t commands 'rustup commands' commands "$@"
//
fn subcommand_details(p: &Parser) -> String {
    debugln!("ZshGen::subcommand_details;");
    // First we do ourself
    let mut ret = vec![format!(
        "\
(( $+functions[_{bin_name_underscore}_commands] )) ||
_{bin_name_underscore}_commands() {{
    local commands; commands=(
        {subcommands_and_args}
    )
    _describe -t commands '{bin_name} commands' commands \"$@\"
}}",
        bin_name_underscore = p.meta.bin_name.as_ref().unwrap().replace(" ", "__"),
        bin_name = p.meta.bin_name.as_ref().unwrap(),
        subcommands_and_args = subcommands_of(p)
    )];

    // Next we start looping through all the children, grandchildren, etc.
    let mut all_subcommands = completions::all_subcommands(p);
    all_subcommands.sort();
    all_subcommands.dedup();
    for &(_, ref bin_name) in &all_subcommands {
        debugln!("ZshGen::subcommand_details:iter: bin_name={}", bin_name);
        ret.push(format!(
            "\
(( $+functions[_{bin_name_underscore}_commands] )) ||
_{bin_name_underscore}_commands() {{
    local commands; commands=(
        {subcommands_and_args}
    )
    _describe -t commands '{bin_name} commands' commands \"$@\"
}}",
            bin_name_underscore = bin_name.replace(" ", "__"),
            bin_name = bin_name,
            subcommands_and_args = subcommands_of(parser_of(p, bin_name))
        ));
    }

    ret.join("\n")
}

// Generates subcommand completions in form of
//
// 		'[arg_name]:[arg_help]'
//
// Where:
//    [arg_name]: the subcommand's name
//    [arg_help]: the help message of the subcommand
//
// A snippet from rustup:
// 		'show:Show the active and installed toolchains'
//      'update:Update Rust toolchains'
fn subcommands_of(p: &Parser) -> String {
    debugln!("ZshGen::subcommands_of;");
    let mut ret = vec![];
    fn add_sc(sc: &App, n: &str, ret: &mut Vec<String>) {
        debugln!("ZshGen::add_sc;");
        let s = format!(
            "\"{name}:{help}\" \\",
            name = n,
            help =
                sc.p.meta
                    .about
                    .unwrap_or("")
                    .replace("[", "\\[")
                    .replace("]", "\\]")
        );
        if !s.is_empty() {
            ret.push(s);
        }
    }

    // The subcommands
    for sc in p.subcommands() {
        debugln!("ZshGen::subcommands_of:iter: subcommand={}", sc.p.meta.name);
        add_sc(sc, &sc.p.meta.name, &mut ret);
        if let Some(ref v) = sc.p.meta.aliases {
            for alias in v.iter().filter(|&&(_, vis)| vis).map(|&(n, _)| n) {
                add_sc(sc, alias, &mut ret);
            }
        }
    }

    ret.join("\n")
}

// Get's the subcommand section of a completion file
// This looks roughly like:
//
// case $state in
// ([bin_name]_args)
//     curcontext=\"${curcontext%:*:*}:[name_hyphen]-command-$words[1]:\"
//     case $line[1] in
//
//         ([name])
//         _arguments -C -s -S \
//             [subcommand_args]
//         && ret=0
//
//         [RECURSIVE_CALLS]
//
//         ;;",
//
//         [repeat]
//
//     esac
// ;;
// esac",
//
// Where the following variables are present:
//    [name] = The subcommand name in the form of "install" for "rustup toolchain install"
//    [bin_name] = The full space delineated bin_name such as "rustup toolchain install"
//    [name_hyphen] = The full space delineated bin_name, but replace spaces with hyphens
//    [repeat] = From the same recursive calls, but for all subcommands
//    [subcommand_args] = The same as zsh::get_args_of
fn get_subcommands_of(p: &Parser) -> String {
    debugln!("get_subcommands_of;");

    debugln!(
        "get_subcommands_of: Has subcommands...{:?}",
        p.has_subcommands()
    );
    if !p.has_subcommands() {
        return String::new();
    }

    let sc_names = completions::subcommands_of(p);

    let mut subcmds = vec![];
    for &(ref name, ref bin_name) in &sc_names {
        let mut v = vec![format!("({})", name)];
        let subcommand_args = get_args_of(parser_of(p, &*bin_name));
        if !subcommand_args.is_empty() {
            v.push(subcommand_args);
        }
        let subcommands = get_subcommands_of(parser_of(p, &*bin_name));
        if !subcommands.is_empty() {
            v.push(subcommands);
        }
        v.push(String::from(";;"));
        subcmds.push(v.join("\n"));
    }

    format!(
        "case $state in
    ({name})
        words=($line[{pos}] \"${{words[@]}}\")
        (( CURRENT += 1 ))
        curcontext=\"${{curcontext%:*:*}}:{name_hyphen}-command-$line[{pos}]:\"
        case $line[{pos}] in
            {subcommands}
        esac
    ;;
esac",
        name = p.meta.name,
        name_hyphen = p.meta.bin_name.as_ref().unwrap().replace(" ", "-"),
        subcommands = subcmds.join("\n"),
        pos = p.positionals().len() + 1
    )
}

fn parser_of<'a, 'b>(p: &'b Parser<'a, 'b>, sc: &str) -> &'b Parser<'a, 'b> {
    debugln!("parser_of: sc={}", sc);
    if sc == p.meta.bin_name.as_ref().unwrap_or(&String::new()) {
        return p;
    }
    &p.find_subcommand(sc).expect(INTERNAL_ERROR_MSG).p
}

// Writes out the args section, which ends up being the flags, opts and postionals, and a jump to
// another ZSH function if there are subcommands.
// The structer works like this:
//    ([conflicting_args]) [multiple] arg [takes_value] [[help]] [: :(possible_values)]
//       ^-- list '-v -h'    ^--'*'          ^--'+'                   ^-- list 'one two three'
//
// An example from the rustup command:
//
// _arguments -C -s -S \
// 		'(-h --help --verbose)-v[Enable verbose output]' \
// 		'(-V -v --version --verbose --help)-h[Prints help information]' \
//      # ... snip for brevity
// 		':: :_rustup_commands' \    # <-- displays subcommands
// 		'*::: :->rustup' \          # <-- displays subcommand args and child subcommands
// 	&& ret=0
//
// The args used for _arguments are as follows:
//    -C: modify the $context internal variable
//    -s: Allow stacking of short args (i.e. -a -b -c => -abc)
//    -S: Do not complete anything after '--' and treat those as argument values
fn get_args_of(p: &Parser) -> String {
    debugln!("get_args_of;");
    let mut ret = vec![String::from("_arguments \"${_arguments_options[@]}\" \\")];
    let opts = write_opts_of(p);
    let flags = write_flags_of(p);
    let positionals = write_positionals_of(p);
    let sc_or_a = if p.has_subcommands() {
        format!(
            "\":: :_{name}_commands\" \\",
            name = p.meta.bin_name.as_ref().unwrap().replace(" ", "__")
        )
    } else {
        String::new()
    };
    let sc = if p.has_subcommands() {
        format!("\"*::: :->{name}\" \\", name = p.meta.name)
    } else {
        String::new()
    };

    if !opts.is_empty() {
        ret.push(opts);
    }
    if !flags.is_empty() {
        ret.push(flags);
    }
    if !positionals.is_empty() {
        ret.push(positionals);
    }
    if !sc_or_a.is_empty() {
        ret.push(sc_or_a);
    }
    if !sc.is_empty() {
        ret.push(sc);
    }
    ret.push(String::from("&& ret=0"));

    ret.join("\n")
}

// Escape help string inside single quotes and brackets
fn escape_help(string: &str) -> String {
    string
        .replace("\\", "\\\\")
        .replace("'", "'\\''")
        .replace("[", "\\[")
        .replace("]", "\\]")
}

// Escape value string inside single quotes and parentheses
fn escape_value(string: &str) -> String {
    string
        .replace("\\", "\\\\")
        .replace("'", "'\\''")
        .replace("(", "\\(")
        .replace(")", "\\)")
        .replace(" ", "\\ ")
}

fn write_opts_of(p: &Parser) -> String {
    debugln!("write_opts_of;");
    let mut ret = vec![];
    for o in p.opts() {
        debugln!("write_opts_of:iter: o={}", o.name());
        let help = o.help().map_or(String::new(), escape_help);
        let mut conflicts = get_zsh_arg_conflicts!(p, o, INTERNAL_ERROR_MSG);
        conflicts = if conflicts.is_empty() {
            String::new()
        } else {
            format!("({})", conflicts)
        };

        let multiple = if o.is_set(ArgSettings::Multiple) {
            "*"
        } else {
            ""
        };
        let pv = if let Some(pv_vec) = o.possible_vals() {
            format!(
                ": :({})",
                pv_vec
                    .iter()
                    .map(|v| escape_value(*v))
                    .collect::<Vec<String>>()
                    .join(" ")
            )
        } else {
            String::new()
        };
        if let Some(short) = o.short() {
            let s = format!(
                "'{conflicts}{multiple}-{arg}+[{help}]{possible_values}' \\",
                conflicts = conflicts,
                multiple = multiple,
                arg = short,
                possible_values = pv,
                help = help
            );

            debugln!("write_opts_of:iter: Wrote...{}", &*s);
            ret.push(s);
        }
        if let Some(long) = o.long() {
            let l = format!(
                "'{conflicts}{multiple}--{arg}=[{help}]{possible_values}' \\",
                conflicts = conflicts,
                multiple = multiple,
                arg = long,
                possible_values = pv,
                help = help
            );

            debugln!("write_opts_of:iter: Wrote...{}", &*l);
            ret.push(l);
        }
    }

    ret.join("\n")
}

fn write_flags_of(p: &Parser) -> String {
    debugln!("write_flags_of;");
    let mut ret = vec![];
    for f in p.flags() {
        debugln!("write_flags_of:iter: f={}", f.name());
        let help = f.help().map_or(String::new(), escape_help);
        let mut conflicts = get_zsh_arg_conflicts!(p, f, INTERNAL_ERROR_MSG);
        conflicts = if conflicts.is_empty() {
            String::new()
        } else {
            format!("({})", conflicts)
        };

        let multiple = if f.is_set(ArgSettings::Multiple) {
            "*"
        } else {
            ""
        };
        if let Some(short) = f.short() {
            let s = format!(
                "'{conflicts}{multiple}-{arg}[{help}]' \\",
                multiple = multiple,
                conflicts = conflicts,
                arg = short,
                help = help
            );

            debugln!("write_flags_of:iter: Wrote...{}", &*s);
            ret.push(s);
        }

        if let Some(long) = f.long() {
            let l = format!(
                "'{conflicts}{multiple}--{arg}[{help}]' \\",
                conflicts = conflicts,
                multiple = multiple,
                arg = long,
                help = help
            );

            debugln!("write_flags_of:iter: Wrote...{}", &*l);
            ret.push(l);
        }
    }

    ret.join("\n")
}

fn write_positionals_of(p: &Parser) -> String {
    debugln!("write_positionals_of;");
    let mut ret = vec![];
    for arg in p.positionals() {
        debugln!("write_positionals_of:iter: arg={}", arg.b.name);
        let a = format!(
            "'{optional}:{name}{help}:{action}' \\",
            optional = if !arg.b.is_set(ArgSettings::Required) {
                ":"
            } else {
                ""
            },
            name = arg.b.name,
            help = arg
                .b
                .help
                .map_or("".to_owned(), |v| " -- ".to_owned() + v)
                .replace("[", "\\[")
                .replace("]", "\\]"),
            action = arg.possible_vals().map_or("_files".to_owned(), |values| {
                format!(
                    "({})",
                    values
                        .iter()
                        .map(|v| escape_value(*v))
                        .collect::<Vec<String>>()
                        .join(" ")
                )
            })
        );

        debugln!("write_positionals_of:iter: Wrote...{}", a);
        ret.push(a);
    }

    ret.join("\n")
}
