// std
use std::collections::{BTreeMap, VecDeque};

// Internal
use app::parser::Parser;
use app::settings::AppSettings as AS;
use args::settings::ArgSettings;
use args::{AnyArg, ArgMatcher, PosBuilder};
use INTERNAL_ERROR_MSG;

// Creates a usage string for display. This happens just after all arguments were parsed, but before
// any subcommands have been parsed (so as to give subcommands their own usage recursively)
pub fn create_usage_with_title(p: &Parser, used: &[&str]) -> String {
    debugln!("usage::create_usage_with_title;");
    let mut usage = String::with_capacity(75);
    usage.push_str("USAGE:\n    ");
    usage.push_str(&*create_usage_no_title(p, used));
    usage
}

// Creates a usage string to be used in error message (i.e. one with currently used args)
pub fn create_error_usage<'a, 'b>(
    p: &Parser<'a, 'b>,
    matcher: &'b ArgMatcher<'a>,
    extra: Option<&str>,
) -> String {
    let mut args: Vec<_> = matcher
        .arg_names()
        .iter()
        .filter(|n| {
            if let Some(o) = find_by_name!(p, **n, opts, iter) {
                !o.b.is_set(ArgSettings::Required) && !o.b.is_set(ArgSettings::Hidden)
            } else if let Some(p) = find_by_name!(p, **n, positionals, values) {
                !p.b.is_set(ArgSettings::Required) && p.b.is_set(ArgSettings::Hidden)
            } else {
                true // flags can't be required, so they're always true
            }
        })
        .map(|&n| n)
        .collect();
    if let Some(r) = extra {
        args.push(r);
    }
    create_usage_with_title(p, &*args)
}

// Creates a usage string (*without title*) if one was not provided by the user manually.
pub fn create_usage_no_title(p: &Parser, used: &[&str]) -> String {
    debugln!("usage::create_usage_no_title;");
    if let Some(u) = p.meta.usage_str {
        String::from(&*u)
    } else if used.is_empty() {
        create_help_usage(p, true)
    } else {
        create_smart_usage(p, used)
    }
}

// Creates a usage string for display in help messages (i.e. not for errors)
pub fn create_help_usage(p: &Parser, incl_reqs: bool) -> String {
    let mut usage = String::with_capacity(75);
    let name = p
        .meta
        .usage
        .as_ref()
        .unwrap_or_else(|| p.meta.bin_name.as_ref().unwrap_or(&p.meta.name));
    usage.push_str(&*name);
    let req_string = if incl_reqs {
        let mut reqs: Vec<&str> = p.required().map(|r| &**r).collect();
        reqs.sort();
        reqs.dedup();
        get_required_usage_from(p, &reqs, None, None, false)
            .iter()
            .fold(String::new(), |a, s| a + &format!(" {}", s)[..])
    } else {
        String::new()
    };

    let flags = needs_flags_tag(p);
    if flags && !p.is_set(AS::UnifiedHelpMessage) {
        usage.push_str(" [FLAGS]");
    } else if flags {
        usage.push_str(" [OPTIONS]");
    }
    if !p.is_set(AS::UnifiedHelpMessage)
        && p.opts
            .iter()
            .any(|o| !o.is_set(ArgSettings::Required) && !o.is_set(ArgSettings::Hidden))
    {
        usage.push_str(" [OPTIONS]");
    }

    usage.push_str(&req_string[..]);

    let has_last = p.positionals.values().any(|p| p.is_set(ArgSettings::Last));
    // places a '--' in the usage string if there are args and options
    // supporting multiple values
    if p.opts.iter().any(|o| o.is_set(ArgSettings::Multiple))
        && p.positionals
            .values()
            .any(|p| !p.is_set(ArgSettings::Required))
        && !(p.has_visible_subcommands() || p.is_set(AS::AllowExternalSubcommands))
        && !has_last
    {
        usage.push_str(" [--]");
    }
    let not_req_or_hidden = |p: &PosBuilder| {
        (!p.is_set(ArgSettings::Required) || p.is_set(ArgSettings::Last))
            && !p.is_set(ArgSettings::Hidden)
    };
    if p.has_positionals() && p.positionals.values().any(not_req_or_hidden) {
        if let Some(args_tag) = get_args_tag(p, incl_reqs) {
            usage.push_str(&*args_tag);
        } else {
            usage.push_str(" [ARGS]");
        }
        if has_last && incl_reqs {
            let pos = p
                .positionals
                .values()
                .find(|p| p.b.is_set(ArgSettings::Last))
                .expect(INTERNAL_ERROR_MSG);
            debugln!("usage::create_help_usage: '{}' has .last(true)", pos.name());
            let req = pos.is_set(ArgSettings::Required);
            if req
                && p.positionals
                    .values()
                    .any(|p| !p.is_set(ArgSettings::Required))
            {
                usage.push_str(" -- <");
            } else if req {
                usage.push_str(" [--] <");
            } else {
                usage.push_str(" [-- <");
            }
            usage.push_str(&*pos.name_no_brackets());
            usage.push_str(">");
            usage.push_str(pos.multiple_str());
            if !req {
                usage.push_str("]");
            }
        }
    }

    // incl_reqs is only false when this function is called recursively
    if p.has_visible_subcommands() && incl_reqs || p.is_set(AS::AllowExternalSubcommands) {
        if p.is_set(AS::SubcommandsNegateReqs) || p.is_set(AS::ArgsNegateSubcommands) {
            if !p.is_set(AS::ArgsNegateSubcommands) {
                usage.push_str("\n    ");
                usage.push_str(&*create_help_usage(p, false));
                usage.push_str(" <SUBCOMMAND>");
            } else {
                usage.push_str("\n    ");
                usage.push_str(&*name);
                usage.push_str(" <SUBCOMMAND>");
            }
        } else if p.is_set(AS::SubcommandRequired) || p.is_set(AS::SubcommandRequiredElseHelp) {
            usage.push_str(" <SUBCOMMAND>");
        } else {
            usage.push_str(" [SUBCOMMAND]");
        }
    }
    usage.shrink_to_fit();
    debugln!("usage::create_help_usage: usage={}", usage);
    usage
}

// Creates a context aware usage string, or "smart usage" from currently used
// args, and requirements
fn create_smart_usage(p: &Parser, used: &[&str]) -> String {
    debugln!("usage::smart_usage;");
    let mut usage = String::with_capacity(75);
    let mut hs: Vec<&str> = p.required().map(|s| &**s).collect();
    hs.extend_from_slice(used);

    let r_string = get_required_usage_from(p, &hs, None, None, false)
        .iter()
        .fold(String::new(), |acc, s| acc + &format!(" {}", s)[..]);

    usage.push_str(
        &p.meta
            .usage
            .as_ref()
            .unwrap_or_else(|| p.meta.bin_name.as_ref().unwrap_or(&p.meta.name))[..],
    );
    usage.push_str(&*r_string);
    if p.is_set(AS::SubcommandRequired) {
        usage.push_str(" <SUBCOMMAND>");
    }
    usage.shrink_to_fit();
    usage
}

// Gets the `[ARGS]` tag for the usage string
fn get_args_tag(p: &Parser, incl_reqs: bool) -> Option<String> {
    debugln!("usage::get_args_tag;");
    let mut count = 0;
    'outer: for pos in p
        .positionals
        .values()
        .filter(|pos| !pos.is_set(ArgSettings::Required))
        .filter(|pos| !pos.is_set(ArgSettings::Hidden))
        .filter(|pos| !pos.is_set(ArgSettings::Last))
    {
        debugln!("usage::get_args_tag:iter:{}:", pos.b.name);
        if let Some(g_vec) = p.groups_for_arg(pos.b.name) {
            for grp_s in &g_vec {
                debugln!("usage::get_args_tag:iter:{}:iter:{};", pos.b.name, grp_s);
                // if it's part of a required group we don't want to count it
                if p.groups.iter().any(|g| g.required && (&g.name == grp_s)) {
                    continue 'outer;
                }
            }
        }
        count += 1;
        debugln!(
            "usage::get_args_tag:iter: {} Args not required or hidden",
            count
        );
    }
    if !p.is_set(AS::DontCollapseArgsInUsage) && count > 1 {
        debugln!("usage::get_args_tag:iter: More than one, returning [ARGS]");
        return None; // [ARGS]
    } else if count == 1 && incl_reqs {
        let pos = p
            .positionals
            .values()
            .find(|pos| {
                !pos.is_set(ArgSettings::Required)
                    && !pos.is_set(ArgSettings::Hidden)
                    && !pos.is_set(ArgSettings::Last)
            })
            .expect(INTERNAL_ERROR_MSG);
        debugln!(
            "usage::get_args_tag:iter: Exactly one, returning '{}'",
            pos.name()
        );
        return Some(format!(
            " [{}]{}",
            pos.name_no_brackets(),
            pos.multiple_str()
        ));
    } else if p.is_set(AS::DontCollapseArgsInUsage) && !p.positionals.is_empty() && incl_reqs {
        debugln!("usage::get_args_tag:iter: Don't collapse returning all");
        return Some(
            p.positionals
                .values()
                .filter(|pos| !pos.is_set(ArgSettings::Required))
                .filter(|pos| !pos.is_set(ArgSettings::Hidden))
                .filter(|pos| !pos.is_set(ArgSettings::Last))
                .map(|pos| format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str()))
                .collect::<Vec<_>>()
                .join(""),
        );
    } else if !incl_reqs {
        debugln!("usage::get_args_tag:iter: incl_reqs=false, building secondary usage string");
        let highest_req_pos = p
            .positionals
            .iter()
            .filter_map(|(idx, pos)| {
                if pos.b.is_set(ArgSettings::Required) && !pos.b.is_set(ArgSettings::Last) {
                    Some(idx)
                } else {
                    None
                }
            })
            .max()
            .unwrap_or_else(|| p.positionals.len());
        return Some(
            p.positionals
                .iter()
                .filter_map(|(idx, pos)| {
                    if idx <= highest_req_pos {
                        Some(pos)
                    } else {
                        None
                    }
                })
                .filter(|pos| !pos.is_set(ArgSettings::Required))
                .filter(|pos| !pos.is_set(ArgSettings::Hidden))
                .filter(|pos| !pos.is_set(ArgSettings::Last))
                .map(|pos| format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str()))
                .collect::<Vec<_>>()
                .join(""),
        );
    }
    Some("".into())
}

// Determines if we need the `[FLAGS]` tag in the usage string
fn needs_flags_tag(p: &Parser) -> bool {
    debugln!("usage::needs_flags_tag;");
    'outer: for f in &p.flags {
        debugln!("usage::needs_flags_tag:iter: f={};", f.b.name);
        if let Some(l) = f.s.long {
            if l == "help" || l == "version" {
                // Don't print `[FLAGS]` just for help or version
                continue;
            }
        }
        if let Some(g_vec) = p.groups_for_arg(f.b.name) {
            for grp_s in &g_vec {
                debugln!("usage::needs_flags_tag:iter:iter: grp_s={};", grp_s);
                if p.groups.iter().any(|g| &g.name == grp_s && g.required) {
                    debugln!("usage::needs_flags_tag:iter:iter: Group is required");
                    continue 'outer;
                }
            }
        }
        if f.is_set(ArgSettings::Hidden) {
            continue;
        }
        debugln!("usage::needs_flags_tag:iter: [FLAGS] required");
        return true;
    }

    debugln!("usage::needs_flags_tag: [FLAGS] not required");
    false
}

// Returns the required args in usage string form by fully unrolling all groups
pub fn get_required_usage_from<'a, 'b>(
    p: &Parser<'a, 'b>,
    reqs: &[&'a str],
    matcher: Option<&ArgMatcher<'a>>,
    extra: Option<&str>,
    incl_last: bool,
) -> VecDeque<String> {
    debugln!(
        "usage::get_required_usage_from: reqs={:?}, extra={:?}",
        reqs,
        extra
    );
    let mut desc_reqs: Vec<&str> = vec![];
    desc_reqs.extend(extra);
    let mut new_reqs: Vec<&str> = vec![];
    macro_rules! get_requires {
        (@group $a: ident, $v:ident, $p:ident) => {{
            if let Some(rl) = p
                .groups
                .iter()
                .filter(|g| g.requires.is_some())
                .find(|g| &g.name == $a)
                .map(|g| g.requires.as_ref().unwrap())
            {
                for r in rl {
                    if !$p.contains(&r) {
                        debugln!(
                            "usage::get_required_usage_from:iter:{}: adding group req={:?}",
                            $a,
                            r
                        );
                        $v.push(r);
                    }
                }
            }
        }};
        ($a:ident, $what:ident, $how:ident, $v:ident, $p:ident) => {{
            if let Some(rl) = p
                .$what
                .$how()
                .filter(|a| a.b.requires.is_some())
                .find(|arg| &arg.b.name == $a)
                .map(|a| a.b.requires.as_ref().unwrap())
            {
                for &(_, r) in rl.iter() {
                    if !$p.contains(&r) {
                        debugln!(
                            "usage::get_required_usage_from:iter:{}: adding arg req={:?}",
                            $a,
                            r
                        );
                        $v.push(r);
                    }
                }
            }
        }};
    }
    // initialize new_reqs
    for a in reqs {
        get_requires!(a, flags, iter, new_reqs, reqs);
        get_requires!(a, opts, iter, new_reqs, reqs);
        get_requires!(a, positionals, values, new_reqs, reqs);
        get_requires!(@group a, new_reqs, reqs);
    }
    desc_reqs.extend_from_slice(&*new_reqs);
    debugln!(
        "usage::get_required_usage_from: after init desc_reqs={:?}",
        desc_reqs
    );
    loop {
        let mut tmp = vec![];
        for a in &new_reqs {
            get_requires!(a, flags, iter, tmp, desc_reqs);
            get_requires!(a, opts, iter, tmp, desc_reqs);
            get_requires!(a, positionals, values, tmp, desc_reqs);
            get_requires!(@group a, tmp, desc_reqs);
        }
        if tmp.is_empty() {
            debugln!("usage::get_required_usage_from: no more children");
            break;
        } else {
            debugln!("usage::get_required_usage_from: after iter tmp={:?}", tmp);
            debugln!(
                "usage::get_required_usage_from: after iter new_reqs={:?}",
                new_reqs
            );
            desc_reqs.extend_from_slice(&*new_reqs);
            new_reqs.clear();
            new_reqs.extend_from_slice(&*tmp);
            debugln!(
                "usage::get_required_usage_from: after iter desc_reqs={:?}",
                desc_reqs
            );
        }
    }
    desc_reqs.extend_from_slice(reqs);
    desc_reqs.sort();
    desc_reqs.dedup();
    debugln!(
        "usage::get_required_usage_from: final desc_reqs={:?}",
        desc_reqs
    );
    let mut ret_val = VecDeque::new();
    let args_in_groups = p
        .groups
        .iter()
        .filter(|gn| desc_reqs.contains(&gn.name))
        .flat_map(|g| p.arg_names_in_group(g.name))
        .collect::<Vec<_>>();

    let pmap = if let Some(m) = matcher {
        desc_reqs
            .iter()
            .filter(|a| p.positionals.values().any(|p| &&p.b.name == a))
            .filter(|&pos| !m.contains(pos))
            .filter_map(|pos| p.positionals.values().find(|x| &x.b.name == pos))
            .filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last))
            .filter(|pos| !args_in_groups.contains(&pos.b.name))
            .map(|pos| (pos.index, pos))
            .collect::<BTreeMap<u64, &PosBuilder>>() // sort by index
    } else {
        desc_reqs
            .iter()
            .filter(|a| p.positionals.values().any(|pos| &&pos.b.name == a))
            .filter_map(|pos| p.positionals.values().find(|x| &x.b.name == pos))
            .filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last))
            .filter(|pos| !args_in_groups.contains(&pos.b.name))
            .map(|pos| (pos.index, pos))
            .collect::<BTreeMap<u64, &PosBuilder>>() // sort by index
    };
    debugln!(
        "usage::get_required_usage_from: args_in_groups={:?}",
        args_in_groups
    );
    for &p in pmap.values() {
        let s = p.to_string();
        if args_in_groups.is_empty() || !args_in_groups.contains(&&*s) {
            ret_val.push_back(s);
        }
    }
    for a in desc_reqs
        .iter()
        .filter(|name| !p.positionals.values().any(|p| &&p.b.name == name))
        .filter(|name| !p.groups.iter().any(|g| &&g.name == name))
        .filter(|name| !args_in_groups.contains(name))
        .filter(|name| !(matcher.is_some() && matcher.as_ref().unwrap().contains(name)))
    {
        debugln!("usage::get_required_usage_from:iter:{}:", a);
        let arg = find_by_name!(p, *a, flags, iter)
            .map(|f| f.to_string())
            .unwrap_or_else(|| {
                find_by_name!(p, *a, opts, iter)
                    .map(|o| o.to_string())
                    .expect(INTERNAL_ERROR_MSG)
            });
        ret_val.push_back(arg);
    }
    let mut g_vec: Vec<String> = vec![];
    for g in desc_reqs
        .iter()
        .filter(|n| p.groups.iter().any(|g| &&g.name == n))
    {
        let g_string = p.args_in_group(g).join("|");
        let elem = format!("<{}>", &g_string[..g_string.len()]);
        if !g_vec.contains(&elem) {
            g_vec.push(elem);
        }
    }
    for g in g_vec {
        ret_val.push_back(g);
    }

    ret_val
}
