// 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 thiserror::Error;

/// An error with argument parsing.
#[sorted]
#[derive(Error, Debug)]
pub enum Error {
    /// 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())),
        }
    })
}

/// 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;
    }
    println!("Argument{}:", if args.len() > 1 { "s" } else { "" });
    for arg in args {
        match arg.short {
            Some(s) => print!(" -{}, ", s),
            None => print!("     "),
        }
        if arg.long.is_empty() {
            print!("  ");
        } else {
            print!("--");
        }
        print!("{:<12}", arg.long);
        if let Some(v) = arg.value {
            if arg.long.is_empty() {
                print!(" ");
            } else {
                print!("=");
            }
            print!("{:<10}", v);
        } else {
            print!("{:<11}", "");
        }
        println!("{}", arg.help);
    }
}

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
        )))
    }

    pub fn parse_numeric<T>(&self) -> Result<T>
    where
        T: TryFrom<u64>,
        <T as TryFrom<u64>>::Error: std::error::Error,
    {
        let val = self.value()?;
        let numres = if val.starts_with("0x") || val.starts_with("0X") {
            u64::from_str_radix(&val[2..], 16)
        } else {
            u64::from_str(val)
        };
        let num = self.handle_parse_err(numres)?;
        self.handle_parse_err(T::try_from(num))
    }

    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());
    }
}
