// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Handles argument parsing.
//!
//! # Example
//!
//! ```
//! # use crosvm::argument::{Argument, Error, print_help, set_arguments};
//! # let args: std::slice::Iter<String> = [].iter();
//! let arguments = &[
//!     Argument::positional("FILES", "files to operate on"),
//!     Argument::short_value('p', "program", "PROGRAM", "Program to apply to each file"),
//!     Argument::short_value('c', "cpus", "N", "Number of CPUs to use. (default: 1)"),
//!     Argument::flag("unmount", "Unmount the root"),
//!     Argument::short_flag('h', "help", "Print help message."),
//! ];
//!
//! let match_res = set_arguments(args, arguments, |name, value| {
//!     match name {
//!         "" => println!("positional arg! {}", value.unwrap()),
//!         "program" => println!("gonna use program {}", value.unwrap()),
//!         "cpus" => {
//!             let v: u32 = value.unwrap().parse().map_err(|_| {
//!                 Error::InvalidValue {
//!                     value: value.unwrap().to_owned(),
//!                     expected: String::from("this value for `cpus` needs to be integer"),
//!                 }
//!             })?;
//!         }
//!         "unmount" => println!("gonna unmount"),
//!         "help" => return Err(Error::PrintHelp),
//!         _ => unreachable!(),
//!     }
//!     unreachable!();
//! });
//!
//! match match_res {
//!     Ok(_) => println!("running with settings"),
//!     Err(Error::PrintHelp) => print_help("best_program", "FILES", arguments),
//!     Err(e) => println!("{}", e),
//! }
//! ```

use std::convert::TryFrom;
use std::result;
use std::str::FromStr;

use remain::sorted;
use terminal_size::{terminal_size, Width};
use thiserror::Error;

/// An error with argument parsing.
#[sorted]
#[derive(Error, Debug)]
pub enum Error {
    /// Free error for use with the `serde_keyvalue` crate parser.
    #[error("failed to parse key-value arguments: {0}")]
    ConfigParserError(String),
    /// The argument was required.
    #[error("expected argument: {0}")]
    ExpectedArgument(String),
    /// The argument expects a value.
    #[error("expected parameter value: {0}")]
    ExpectedValue(String),
    /// The argument's given value is invalid.
    #[error("invalid value {value:?}: {expected}")]
    InvalidValue { value: String, expected: String },
    /// The help information was requested
    #[error("help was requested")]
    PrintHelp,
    /// There was a syntax error with the argument.
    #[error("syntax error: {0}")]
    Syntax(String),
    /// The argument was already given and none more are expected.
    #[error("too many arguments: {0}")]
    TooManyArguments(String),
    /// The argument does not expect a value.
    #[error("unexpected parameter value: {0}")]
    UnexpectedValue(String),
    /// The argument's name is unused.
    #[error("unknown argument: {0}")]
    UnknownArgument(String),
}

/// Result of a argument parsing.
pub type Result<T> = result::Result<T, Error>;

#[derive(Debug, PartialEq)]
pub enum ArgumentValueMode {
    /// Specifies that an argument requires a value and that an error should be generated if
    /// no value is provided during parsing.
    Required,

    /// Specifies that an argument does not allow a value and that an error should be returned
    /// if a value is provided during parsing.
    Disallowed,

    /// Specifies that an argument may have a value during parsing but is not required to.
    Optional,
}

/// Information about an argument expected from the command line.
///
/// # Examples
///
/// To indicate a flag style argument:
///
/// ```
/// # use crosvm::argument::Argument;
/// Argument::short_flag('f', "flag", "enable awesome mode");
/// ```
///
/// To indicate a parameter style argument that expects a value:
///
/// ```
/// # use crosvm::argument::Argument;
/// // "VALUE" and "NETMASK" are placeholder values displayed in the help message for these
/// // arguments.
/// Argument::short_value('v', "val", "VALUE", "how much do you value this usage information");
/// Argument::value("netmask", "NETMASK", "hides your netface");
/// ```
///
/// To indicate an argument with no short version:
///
/// ```
/// # use crosvm::argument::Argument;
/// Argument::flag("verbose", "this option is hard to type quickly");
/// ```
///
/// To indicate a positional argument:
///
/// ```
/// # use crosvm::argument::Argument;
/// Argument::positional("VALUES", "these are positional arguments");
/// ```
pub struct Argument {
    /// The name of the value to display in the usage information.
    pub value: Option<&'static str>,
    /// Specifies how values should be handled for this this argument.
    pub value_mode: ArgumentValueMode,
    /// Optional single character shortened argument name.
    pub short: Option<char>,
    /// The long name of this argument.
    pub long: &'static str,
    /// Helpfuly usage information for this argument to display to the user.
    pub help: &'static str,
}

impl Argument {
    pub fn positional(value: &'static str, help: &'static str) -> Argument {
        Argument {
            value: Some(value),
            value_mode: ArgumentValueMode::Required,
            short: None,
            long: "",
            help,
        }
    }

    pub fn value(long: &'static str, value: &'static str, help: &'static str) -> Argument {
        Argument {
            value: Some(value),
            value_mode: ArgumentValueMode::Required,
            short: None,
            long,
            help,
        }
    }

    pub fn short_value(
        short: char,
        long: &'static str,
        value: &'static str,
        help: &'static str,
    ) -> Argument {
        Argument {
            value: Some(value),
            value_mode: ArgumentValueMode::Required,
            short: Some(short),
            long,
            help,
        }
    }

    pub fn flag(long: &'static str, help: &'static str) -> Argument {
        Argument {
            value: None,
            value_mode: ArgumentValueMode::Disallowed,
            short: None,
            long,
            help,
        }
    }

    pub fn short_flag(short: char, long: &'static str, help: &'static str) -> Argument {
        Argument {
            value: None,
            value_mode: ArgumentValueMode::Disallowed,
            short: Some(short),
            long,
            help,
        }
    }

    pub fn flag_or_value(long: &'static str, value: &'static str, help: &'static str) -> Argument {
        Argument {
            value: Some(value),
            value_mode: ArgumentValueMode::Optional,
            short: None,
            long,
            help,
        }
    }
}

fn parse_arguments<I, R, F>(args: I, mut f: F) -> Result<()>
where
    I: Iterator<Item = R>,
    R: AsRef<str>,
    F: FnMut(&str, Option<&str>) -> Result<()>,
{
    enum State {
        // Initial state at the start and after finishing a single argument/value.
        Top,
        // The remaining arguments are all positional.
        Positional,
        // The next string is the value for the argument `name`.
        Value { name: String },
    }
    let mut s = State::Top;
    for arg in args {
        let arg = arg.as_ref();
        loop {
            let mut arg_consumed = true;
            s = match s {
                State::Top => {
                    if arg == "--" {
                        State::Positional
                    } else if arg.starts_with("--") {
                        let param = arg.trim_start_matches('-');
                        if param.contains('=') {
                            let mut iter = param.splitn(2, '=');
                            let name = iter.next().unwrap();
                            let value = iter.next().unwrap();
                            if name.is_empty() {
                                return Err(Error::Syntax(
                                    "expected parameter name before `=`".to_owned(),
                                ));
                            }
                            if value.is_empty() {
                                return Err(Error::Syntax(
                                    "expected parameter value after `=`".to_owned(),
                                ));
                            }
                            f(name, Some(value))?;
                            State::Top
                        } else {
                            State::Value {
                                name: param.to_owned(),
                            }
                        }
                    } else if arg.starts_with('-') {
                        if arg.len() == 1 {
                            return Err(Error::Syntax(
                                "expected argument short name after `-`".to_owned(),
                            ));
                        }
                        let name = &arg[1..2];
                        let value = if arg.len() > 2 { Some(&arg[2..]) } else { None };
                        if let Err(e) = f(name, value) {
                            if let Error::ExpectedValue(_) = e {
                                State::Value {
                                    name: name.to_owned(),
                                }
                            } else {
                                return Err(e);
                            }
                        } else {
                            State::Top
                        }
                    } else {
                        f("", Some(arg))?;
                        State::Positional
                    }
                }
                State::Positional => {
                    f("", Some(arg))?;
                    State::Positional
                }
                State::Value { name } => {
                    if arg.starts_with('-') {
                        arg_consumed = false;
                        f(&name, None)?;
                    } else if let Err(e) = f(&name, Some(arg)) {
                        arg_consumed = false;
                        f(&name, None).map_err(|_| e)?;
                    }
                    State::Top
                }
            };

            if arg_consumed {
                break;
            }
        }
    }

    // If we ran out of arguments while parsing the last parameter, which may be either a
    // value parameter or a flag, try to parse it as a flag. This will produce "missing value"
    // error if the parameter is in fact a value parameter, which is the desired outcome.
    match s {
        State::Value { name } => f(&name, None),
        _ => Ok(()),
    }
}

/// Parses the given `args` against the list of know arguments `arg_list` and calls `f` with each
/// present argument and value if required.
///
/// This function guarantees that only valid long argument names from `arg_list` are sent to the
/// callback `f`. It is also guaranteed that if an arg requires a value (i.e.
/// `arg.value.is_some()`), the value will be `Some` in the callbacks arguments. If the callback
/// returns `Err`, this function will end parsing and return that `Err`.
///
/// See the [module level](index.html) example for a usage example.
pub fn set_arguments<I, R, F>(args: I, arg_list: &[Argument], mut f: F) -> Result<()>
where
    I: Iterator<Item = R>,
    R: AsRef<str>,
    F: FnMut(&str, Option<&str>) -> Result<()>,
{
    parse_arguments(args, |name, value| {
        let mut matches = None;
        for arg in arg_list {
            if let Some(short) = arg.short {
                if name.len() == 1 && name.starts_with(short) {
                    if value.is_some() != arg.value.is_some() {
                        return Err(Error::ExpectedValue(short.to_string()));
                    }
                    matches = Some(arg.long);
                }
            }
            if matches.is_none() && arg.long == name {
                if value.is_none() && arg.value_mode == ArgumentValueMode::Required {
                    return Err(Error::ExpectedValue(arg.long.to_owned()));
                }
                if value.is_some() && arg.value_mode == ArgumentValueMode::Disallowed {
                    return Err(Error::UnexpectedValue(arg.long.to_owned()));
                }
                matches = Some(arg.long);
            }
        }
        match matches {
            Some(long) => f(long, value),
            None => Err(Error::UnknownArgument(name.to_owned())),
        }
    })
}

const DEFAULT_COLUMNS: usize = 80;

/// Get the number of columns on a display, with a reasonable default.
fn get_columns() -> usize {
    if let Some((Width(columns), _)) = terminal_size() {
        return columns.into();
    }
    DEFAULT_COLUMNS
}

/// Poor man's reflowing function for string. This function will unsplit the
/// lines, an empty line splits a paragraph.
fn reflow(s: &str, offset: usize, width: usize) -> String {
    let mut lines: Vec<String> = vec![];
    let mut prev = "";
    let filler = " ".repeat(offset);
    for line in s.lines() {
        let line = line.trim();
        if line.is_empty() {
            // Skip the empty line, the paragraph delimiter.
        } else if prev.is_empty() {
            // Start a new paragraph if the previous line was empty.
            lines.push(line.to_string());
        } else if let Some(last) = lines.last_mut() {
            *last += " ";
            *last += line;
        }
        prev = line;
    }
    let mut lines = lines.into_iter().flat_map(|line| {
        let mut output = vec![];
        // Split the line with the last space found, or if the word exceeds
        // length of one line, give up and use the full width.
        let mut line = line.as_str();
        while let Some(s) = line.get(0..width) {
            let offset = s.rfind(" ").unwrap_or(s.len());
            output.push(s[0..offset].to_string());
            line = &line[offset + 1..];
        }
        // Here we should have the remaining part of the line that is less
        // than `width`.
        output.push(line.to_string());

        output
    });
    match lines.next() {
        None => String::new(),
        Some(line) => std::iter::once(line)
            .chain(lines.map(|line| filler.clone() + &line))
            .collect::<Vec<_>>()
            .join("\n"),
    }
}

/// Obtain the leading part of the help message. The output is later processed
/// to reflow. Depending on how short this, newline is used.
fn get_leading_part(arg: &Argument) -> String {
    [
        match arg.short {
            Some(s) => format!(" -{}, ", s),
            None => "     ".to_string(),
        },
        if arg.long.is_empty() {
            "  ".to_string()
        } else {
            "--".to_string()
        },
        format!("{:<12}", arg.long),
        if let Some(v) = arg.value {
            format!("{}{:<9} ", if arg.long.is_empty() { " " } else { "=" }, v)
        } else {
            " ".to_string()
        },
    ]
    .join("")
}

/// Prints command line usage information to stdout.
///
/// Usage information is printed according to the help fields in `args` with a leading usage line.
/// The usage line is of the format "`program_name` \[ARGUMENTS\] `required_arg`".
pub fn print_help(program_name: &str, required_arg: &str, args: &[Argument]) {
    println!(
        "Usage: {} {}{}\n",
        program_name,
        if args.is_empty() { "" } else { "[ARGUMENTS] " },
        required_arg
    );
    if args.is_empty() {
        return;
    }

    let indent_depth = 30;
    let minimum_width_of_help = DEFAULT_COLUMNS - 1 - indent_depth;
    let columns = get_columns();
    let columns = minimum_width_of_help.max(columns - indent_depth);

    println!("Argument{}:", if args.len() > 1 { "s" } else { "" });
    for arg in args {
        let leading_part = get_leading_part(arg);
        if leading_part.len() <= indent_depth {
            print!(
                "{}{}",
                leading_part,
                " ".repeat(indent_depth - leading_part.len())
            );
        } else {
            print!("{}\n{}", leading_part, " ".repeat(indent_depth));
        }
        println!("{}", reflow(arg.help, indent_depth, columns));
    }
}

pub fn parse_hex_or_decimal(maybe_hex_string: &str) -> Result<u64> {
    // Parse string starting with 0x as hex and others as numbers.
    if let Some(hex_string) = maybe_hex_string.strip_prefix("0x") {
        u64::from_str_radix(hex_string, 16)
    } else if let Some(hex_string) = maybe_hex_string.strip_prefix("0X") {
        u64::from_str_radix(hex_string, 16)
    } else {
        u64::from_str(maybe_hex_string)
    }
    .map_err(|e| Error::InvalidValue {
        value: maybe_hex_string.to_string(),
        expected: e.to_string(),
    })
}

pub struct KeyValuePair<'a> {
    context: &'a str,
    key: &'a str,
    value: Option<&'a str>,
}

impl<'a> KeyValuePair<'a> {
    fn handle_parse_err<T, E: std::error::Error>(
        &self,
        result: std::result::Result<T, E>,
    ) -> Result<T> {
        result.map_err(|e| {
            self.invalid_value_err(format!(
                "Failed to parse parameter `{}` as {}: {}",
                self.key,
                std::any::type_name::<T>(),
                e
            ))
        })
    }

    pub fn key(&self) -> &'a str {
        self.key
    }

    pub fn value(&self) -> Result<&'a str> {
        self.value.ok_or(Error::ExpectedValue(format!(
            "{}: parameter `{}` requires a value",
            self.context, self.key
        )))
    }

    fn get_numeric<T>(&self, val: &str) -> Result<T>
    where
        T: TryFrom<u64>,
        <T as TryFrom<u64>>::Error: std::error::Error,
    {
        let num = parse_hex_or_decimal(val)?;
        self.handle_parse_err(T::try_from(num))
    }

    pub fn parse_numeric<T>(&self) -> Result<T>
    where
        T: TryFrom<u64>,
        <T as TryFrom<u64>>::Error: std::error::Error,
    {
        let val = self.value()?;
        self.get_numeric(val)
    }

    pub fn key_numeric<T>(&self) -> Result<T>
    where
        T: TryFrom<u64>,
        <T as TryFrom<u64>>::Error: std::error::Error,
    {
        self.get_numeric(self.key())
    }

    pub fn parse<T>(&self) -> Result<T>
    where
        T: FromStr,
        <T as FromStr>::Err: std::error::Error,
    {
        self.handle_parse_err(T::from_str(self.value()?))
    }

    pub fn parse_or<T>(&self, default: T) -> Result<T>
    where
        T: FromStr,
        <T as FromStr>::Err: std::error::Error,
    {
        match self.value {
            Some(v) => self.handle_parse_err(T::from_str(v)),
            None => Ok(default),
        }
    }

    pub fn invalid_key_err(&self) -> Error {
        Error::UnknownArgument(format!(
            "{}: Unknown parameter `{}`",
            self.context, self.key
        ))
    }

    pub fn invalid_value_err(&self, description: String) -> Error {
        Error::InvalidValue {
            value: self
                .value
                .expect("invalid value error without value")
                .to_string(),
            expected: format!("{}: {}", self.context, description),
        }
    }
}

/// Parse a string of delimiter-separated key-value options. This is intended to simplify parsing
/// of command-line options that take a bunch of parameters encoded into the argument, e.g. for
/// setting up an emulated hardware device. Returns an Iterator of KeyValuePair, which provides
/// convenience functions to parse numeric values and performs appropriate error handling.
///
/// `flagname` - name of the command line parameter, used as context in error messages
/// `s` - the string to parse
/// `delimiter` - the character that separates individual pairs
///
/// Usage example:
/// ```
/// # use crosvm::argument::{Result, parse_key_value_options};
///
/// fn parse_turbo_button_parameters(s: &str) -> Result<(String, u32, bool)> {
///     let mut color = String::new();
///     let mut speed = 0u32;
///     let mut turbo = false;
///
///     for opt in parse_key_value_options("turbo-button", s, ',') {
///         match opt.key() {
///             "color" => color = opt.value()?.to_string(),
///             "speed" => speed = opt.parse_numeric::<u32>()?,
///             "turbo" => turbo = opt.parse_or::<bool>(true)?,
///             _ => return Err(opt.invalid_key_err()),
///         }
///     }
///
///     Ok((color, speed, turbo))
/// }
///
/// assert_eq!(parse_turbo_button_parameters("color=red,speed=0xff,turbo").unwrap(),
///            ("red".to_string(), 0xff, true))
/// ```
///
/// TODO: upgrade `delimiter` to generic Pattern support once that has been stabilized
/// at <https://github.com/rust-lang/rust/issues/27721>.
pub fn parse_key_value_options<'a>(
    flagname: &'a str,
    s: &'a str,
    delimiter: char,
) -> impl Iterator<Item = KeyValuePair<'a>> {
    s.split(delimiter)
        .map(|frag| frag.splitn(2, '='))
        .map(move |mut kv| KeyValuePair {
            context: flagname,
            key: kv.next().unwrap_or(""),
            value: kv.next(),
        })
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn request_help() {
        let arguments = [Argument::short_flag('h', "help", "Print help message.")];

        let match_res = set_arguments(["-h"].iter(), &arguments[..], |name, _| match name {
            "help" => Err(Error::PrintHelp),
            _ => unreachable!(),
        });
        match match_res {
            Err(Error::PrintHelp) => {}
            _ => unreachable!(),
        }
    }

    #[test]
    fn mixed_args() {
        let arguments = [
            Argument::positional("FILES", "files to operate on"),
            Argument::short_value('p', "program", "PROGRAM", "Program to apply to each file"),
            Argument::short_value('c', "cpus", "N", "Number of CPUs to use. (default: 1)"),
            Argument::flag("unmount", "Unmount the root"),
            Argument::short_flag('h', "help", "Print help message."),
        ];

        let mut unmount = false;
        let match_res = set_arguments(
            ["--cpus", "3", "--program", "hello", "--unmount", "file"].iter(),
            &arguments[..],
            |name, value| {
                match name {
                    "" => assert_eq!(value.unwrap(), "file"),
                    "program" => assert_eq!(value.unwrap(), "hello"),
                    "cpus" => {
                        let c: u32 = value.unwrap().parse().map_err(|_| Error::InvalidValue {
                            value: value.unwrap().to_owned(),
                            expected: String::from("this value for `cpus` needs to be integer"),
                        })?;
                        assert_eq!(c, 3);
                    }
                    "unmount" => unmount = true,
                    "help" => return Err(Error::PrintHelp),
                    _ => unreachable!(),
                };
                Ok(())
            },
        );
        assert!(match_res.is_ok());
        assert!(unmount);
    }

    #[test]
    fn name_value_pair() {
        let arguments = [Argument::short_value(
            'c',
            "cpus",
            "N",
            "Number of CPUs to use. (default: 1)",
        )];
        let match_res = set_arguments(
            ["-c", "5", "--cpus", "5", "-c5", "--cpus=5"].iter(),
            &arguments[..],
            |name, value| {
                assert_eq!(name, "cpus");
                assert_eq!(value, Some("5"));
                Ok(())
            },
        );
        assert!(match_res.is_ok());
        let not_match_res = set_arguments(
            ["-c", "5", "--cpus"].iter(),
            &arguments[..],
            |name, value| {
                assert_eq!(name, "cpus");
                assert_eq!(value, Some("5"));
                Ok(())
            },
        );
        assert!(not_match_res.is_err());
    }

    #[test]
    fn flag_or_value() {
        let run_case = |args| -> Option<String> {
            let arguments = [
                Argument::positional("FILES", "files to operate on"),
                Argument::flag_or_value("gpu", "[2D|3D]", "Enable or configure gpu"),
                Argument::flag("foo", "Enable foo."),
                Argument::value("bar", "stuff", "Configure bar."),
            ];

            let mut gpu_value: Option<String> = None;
            let match_res =
                set_arguments(args, &arguments[..], |name: &str, value: Option<&str>| {
                    match name {
                        "" => assert_eq!(value.unwrap(), "file1"),
                        "foo" => assert!(value.is_none()),
                        "bar" => assert_eq!(value.unwrap(), "stuff"),
                        "gpu" => match value {
                            Some(v) => match v {
                                "2D" | "3D" => {
                                    gpu_value = Some(v.to_string());
                                }
                                _ => {
                                    return Err(Error::InvalidValue {
                                        value: v.to_string(),
                                        expected: String::from("2D or 3D"),
                                    })
                                }
                            },
                            None => {
                                gpu_value = None;
                            }
                        },
                        _ => unreachable!(),
                    };
                    Ok(())
                });

            assert!(match_res.is_ok());
            gpu_value
        };

        // Used as flag and followed by positional
        assert_eq!(run_case(["--gpu", "file1"].iter()), None);
        // Used as flag and followed by flag
        assert_eq!(run_case(["--gpu", "--foo", "file1",].iter()), None);
        // Used as flag and followed by value
        assert_eq!(run_case(["--gpu", "--bar=stuff", "file1"].iter()), None);

        // Used as value and followed by positional
        assert_eq!(run_case(["--gpu=2D", "file1"].iter()).unwrap(), "2D");
        // Used as value and followed by flag
        assert_eq!(run_case(["--gpu=2D", "--foo"].iter()).unwrap(), "2D");
        // Used as value and followed by value
        assert_eq!(
            run_case(["--gpu=2D", "--bar=stuff", "file1"].iter()).unwrap(),
            "2D"
        );
    }

    #[test]
    fn parse_key_value_options_simple() {
        let mut opts = parse_key_value_options("test", "fruit=apple,number=13,flag,hex=0x123", ',');

        let kv1 = opts.next().unwrap();
        assert_eq!(kv1.key(), "fruit");
        assert_eq!(kv1.value().unwrap(), "apple");

        let kv2 = opts.next().unwrap();
        assert_eq!(kv2.key(), "number");
        assert_eq!(kv2.parse::<u32>().unwrap(), 13);

        let kv3 = opts.next().unwrap();
        assert_eq!(kv3.key(), "flag");
        assert!(kv3.value().is_err());
        assert!(kv3.parse_or::<bool>(true).unwrap());

        let kv4 = opts.next().unwrap();
        assert_eq!(kv4.key(), "hex");
        assert_eq!(kv4.parse_numeric::<u32>().unwrap(), 0x123);

        assert!(opts.next().is_none());
    }

    #[test]
    fn parse_key_value_options_overflow() {
        let mut opts = parse_key_value_options("test", "key=1000000000000000", ',');
        let kv = opts.next().unwrap();
        assert!(kv.parse::<u32>().is_err());
        assert!(kv.parse_numeric::<u32>().is_err());
    }

    #[test]
    fn parse_hex_or_decimal_simple() {
        assert_eq!(parse_hex_or_decimal("15").unwrap(), 15);
        assert_eq!(parse_hex_or_decimal("0x15").unwrap(), 0x15);
        assert_eq!(parse_hex_or_decimal("0X15").unwrap(), 0x15);
        assert!(parse_hex_or_decimal("0xz").is_err());
        assert!(parse_hex_or_decimal("hello world").is_err());
    }

    #[test]
    fn parse_key_value_options_numeric_key() {
        let mut opts = parse_key_value_options("test", "0x30,0x100=value,nonnumeric=value", ',');
        let kv = opts.next().unwrap();
        assert_eq!(kv.key_numeric::<u32>().unwrap(), 0x30);

        let kv = opts.next().unwrap();
        assert_eq!(kv.key_numeric::<u32>().unwrap(), 0x100);
        assert_eq!(kv.value().unwrap(), "value");

        let kv = opts.next().unwrap();
        assert!(kv.key_numeric::<u32>().is_err());
        assert_eq!(kv.key(), "nonnumeric");
    }

    #[test]
    fn reflow_simple() {
        assert_eq!(reflow("Hello world, this is a sample of reflowing operation that should work generally. However I don't know if it is useful", 10, 40),
        "Hello world, this is a sample of
          reflowing operation that should work
          generally. However I don't know if it
          is useful");
    }

    #[test]
    fn reflow_paragraph() {
        assert_eq!(
            reflow(
                "Hello world, this is a sample of reflowing operation that should work generally.

I am going to give you another paragraph. However I don't know if it is useful",
                10,
                40
            ),
            "Hello world, this is a sample of
          reflowing operation that should work
          generally.
          I am going to give you another
          paragraph. However I don't know if it
          is useful"
        );
    }

    #[test]
    fn get_leading_part_short() {
        assert_eq!(
            get_leading_part(&Argument::positional("FILES", "files to operate on")).len(),
            30
        );
        assert_eq!(
            get_leading_part(&Argument::flag_or_value(
                "gpu",
                "[2D|3D]",
                "Enable or configure gpu"
            ))
            .len(),
            30
        );
        assert_eq!(
            get_leading_part(&Argument::flag("foo", "Enable foo.")).len(),
            20
        );
        assert_eq!(
            get_leading_part(&Argument::value("bar", "stuff", "Configure bar.")).len(),
            30
        );
    }

    #[test]
    fn get_leading_part_long() {
        assert_eq!(
            get_leading_part(&Argument::value(
                "very-long-flag-name",
                "stuff",
                "Configure bar."
            ))
            .len(),
            37
        );
    }
}
