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

use {
    crate::common_operations::allowed_ops,
    crate::target::{AvailableTargets, TargetOps},
    clap::{App, Arg},
    log::error,
    std::{env, ffi::OsString, ops::RangeInclusive},
    thiserror::Error,
};

#[derive(Debug, Error, PartialEq)]
pub enum Error {
    #[error("Operation not supported for the target.")]
    OperationNotSupported,

    #[error("Block size cannot be greater than 8192 when log_ftrace is enabled")]
    LargeBlockSizeWithLogFtrace,
}

#[derive(Debug)]
pub struct ParseArgs {
    /// Limit on number of outstanding IOs - IOs that are generated but are not
    /// complete.
    pub queue_depth: usize,

    /// odu writes a header at the beginning of each block boundary. When not
    /// passed as a parameter an attempt may be made to guess the block size. On
    /// failure to get block size, a default block size is chosen. This helps
    /// odu to verify the success of the operation. See also `align` and
    /// `max_io_size`.
    pub block_size: u64,

    /// Maximum size of the IO issued. This parameter specifies the number of
    /// bytes read/written from/to the `target` in one operation.
    pub max_io_size: u64,

    /// If set to true, IOs are aligned to `block_size`. If set to false, a
    /// random offset is chosen to issue IOs.
    pub align: bool,

    /// Number of IO operations to generate. This number does not include IOs
    /// issued to verify.
    pub max_io_count: u64,

    /// IOs are issued on the `target` for a range of offset between
    /// [0, `target_length`). The bytes from offset `target_length` till end of
    /// target are not to operated on.
    pub target_length: u64,

    /// Configures number of IO issuing threads. IO issuing threads are
    /// generally not cpu bound. There may be more threads in the process to
    /// generate load and to verify the IO.
    pub thread_count: usize,

    /// Specifies how a `target` is opened, what type of IO functions are called
    /// and how completions of those IOs will be delivered. For example fdio
    /// might call posix-like pwrite, pread, etc. but blob target may have
    /// completely different restrictions on issuing IOs.
    pub target_type: AvailableTargets,

    /// These are the set of operations for which generator will generate
    /// io packets. These operation performance is what user is interested
    /// in.
    pub operations: TargetOps,

    /// When true, the `target` access (read/write) are sequential with respect
    /// to offsets within the `target`.
    pub sequential: bool,

    /// Parameters passed to odu gets written to `output_config_file`.
    pub output_config_file: String,

    /// A `target` can be a path in filesystem, a hash in blobfs, a path in
    /// device tree, or a named pipe. These are pre-existing targets that have
    /// a non-zero length. IOs are performed only on these targets. All threads
    /// get exclusive access to certain parts of the `target`.
    pub target: String,

    /// If true, generates ftrace events on IO completion. Disabled by default.
    pub log_ftrace: bool,

    /// If false, retains all the files and directories created during run. This is useful to
    /// analyze any bugs during the run.
    pub cleanup: bool,
}

const KIB: u64 = 1024;
const MIB: u64 = KIB * KIB;

// TODO(auradkar): Some of the default values/ranges are intentionally set low
//                 so that the tool runs for shorter duration.
//                 And some of the defaults and ranges have arbitrarily values.
//                 We need to come up with better ones.
const QUEUE_DEPTH_RANGE: RangeInclusive<usize> = 1..=256;
const QUEUE_DEPTH_DEFAULT: usize = 40;

const BLOCK_SIZE_RANGE: RangeInclusive<u64> = 1..=MIB;
const BLOCK_SIZE_DEFAULT: u64 = 8 * KIB;

const MAX_IO_SIZE_RANGE: RangeInclusive<u64> = 1..=MIB;
const MAX_IO_SIZE_DEFAULT: u64 = MIB;

const ALIGN_DEFAULT: bool = true;

const MAX_IO_COUNT_RANGE: RangeInclusive<u64> = 1..=2_000_000;
const MAX_IO_COUNT_DEFAULT: u64 = 1000;

const TARGET_SIZE_DEFAULT: u64 = 20 * MIB;

const THREAD_COUNT_RANGE: RangeInclusive<usize> = 1..=16;
const THREAD_COUNT_DEFAULT: usize = 3;

const TARGET_OPERATIONS_DEFAULT: &str = "write";

const TARGET_TYPE_DEFAULT: AvailableTargets = AvailableTargets::FileTarget;

const SEQUENTIAL_DEFAULT: bool = true;

const OUTPUT_CONFIG_FILE_DEFAULT: &str = "/tmp/output.config";

const LOG_FTRACE: bool = false;

const CLEANUP: bool = true;

fn to_string_min_max<T: std::fmt::Debug>(val: RangeInclusive<T>) -> String {
    format!("Min:{:?} Max:{:?}", val.start(), val.end())
}

fn validate_range<T: std::str::FromStr + std::cmp::PartialOrd>(
    key: &str,
    val: String,
    range: RangeInclusive<T>,
) -> Result<(), String> {
    let arg =
        val.parse::<T>().map_err(|_| format!("{} expects a number. Found \"{}\"", key, val))?;

    if !range.contains(&arg) {
        return Err(format!(" {} value {} out of range.", key, val));
    }

    Ok(())
}

fn queue_depth_validator(val: String) -> Result<(), String> {
    validate_range("queue_depth", val, QUEUE_DEPTH_RANGE)
}

fn block_size_validator(val: String) -> Result<(), String> {
    validate_range("block_size", val, BLOCK_SIZE_RANGE)
}

fn max_io_size_validator(val: String) -> Result<(), String> {
    validate_range("max_io_size", val, MAX_IO_SIZE_RANGE)
}

fn max_io_count_validator(val: String) -> Result<(), String> {
    validate_range("max_io_count", val, MAX_IO_COUNT_RANGE)
}

fn thread_count_validator(val: String) -> Result<(), String> {
    validate_range("thread_count", val, THREAD_COUNT_RANGE)
}

fn target_operations_validator(
    target_type: AvailableTargets,
    operations: &Vec<&str>,
) -> Result<TargetOps, Error> {
    // Get the operations allowed by the target and see if the operations requested
    // is subset of the operations allowed.
    let allowed_ops = allowed_ops(target_type);

    let mut ops = TargetOps { write: false, open: false, read: false };
    for value in operations {
        if !allowed_ops.enabled(value) {
            error!(
                "{:?} is not allowed for target: {}",
                value,
                AvailableTargets::value_to_friendly_name(target_type)
            );
            error!(
                "For target: {}, supported operations are {:?}",
                AvailableTargets::value_to_friendly_name(target_type),
                allowed_ops.enabled_operation_names()
            );
            return Err(Error::OperationNotSupported);
        } else {
            ops.enable(value, true).unwrap();
        }
    }

    return Ok(ops);
}

fn parse_from<I, T>(iter: I) -> Result<ParseArgs, Error>
where
    I: IntoIterator<Item = T>,
    T: Into<OsString> + Clone,
{
    let queue_depth_default_str = &format!("{}", QUEUE_DEPTH_DEFAULT);
    let block_size_default_str = &format!("{}", BLOCK_SIZE_DEFAULT);
    let max_io_size_default_str = &format!("{}", MAX_IO_SIZE_DEFAULT);
    let align_default_str = &format!("{}", ALIGN_DEFAULT);
    let max_io_count_default_str = &format!("{}", MAX_IO_COUNT_DEFAULT);
    let target_size_default_str = &format!("{}", TARGET_SIZE_DEFAULT);
    let thread_count_default_str = &format!("{}", THREAD_COUNT_DEFAULT);
    let target_operations_default_str = &format!("{}", TARGET_OPERATIONS_DEFAULT);
    let target_type_default_str =
        &format!("{}", AvailableTargets::value_to_friendly_name(TARGET_TYPE_DEFAULT));
    let sequential_default_str = &format!("{}", SEQUENTIAL_DEFAULT);
    let output_config_file_default_str = &format!("{}", OUTPUT_CONFIG_FILE_DEFAULT);
    let log_ftrace_default_str = &format!("{}", LOG_FTRACE);
    let cleanup_default_str = &format!("{}", CLEANUP);

    let matches = App::new("odu")
        // TODO: We cannot get package version through `CARGO_PKG_VERSION`.
        //       Find out a way.
        .version("0.1.0")
        .about("IO benchmarking library and utility")
        .arg(
            Arg::with_name("queue_depth")
                .short("q")
                .long("queue_depth")
                .value_name(&to_string_min_max(QUEUE_DEPTH_RANGE))
                .default_value(queue_depth_default_str)
                .validator(queue_depth_validator)
                .help("Maximum number of outstanding IOs per thread.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("block_size")
                .short("b")
                .long("block_size")
                .value_name(&to_string_min_max(BLOCK_SIZE_RANGE))
                .default_value(&block_size_default_str)
                .validator(block_size_validator)
                .help("Maximum number of outstanding IOs per thread.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("max_io_size")
                .short("i")
                .long("max_io_size")
                .value_name(&to_string_min_max(MAX_IO_SIZE_RANGE))
                .default_value(&max_io_size_default_str)
                .validator(max_io_size_validator)
                .help("Maximum number of outstanding IOs per thread.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("align")
                .short("a")
                .long("align")
                .possible_values(&["true", "false"])
                .default_value(&align_default_str)
                .help("Maximum number of outstanding IOs per thread.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("max_io_count")
                .short("c")
                .long("max_io_count")
                .value_name(&to_string_min_max(MAX_IO_COUNT_RANGE))
                .default_value(&max_io_count_default_str)
                .validator(max_io_count_validator)
                .help("Maximum number of outstanding IOs per thread.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("target_length")
                .short("l")
                .long("target_length")
                .value_name(&to_string_min_max(0..=std::u64::MAX))
                .default_value(&target_size_default_str)
                .help("Maximum number of outstanding IOs per thread.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("thread_count")
                .short("d")
                .long("thread_count")
                .value_name(&to_string_min_max(THREAD_COUNT_RANGE))
                .default_value(&thread_count_default_str)
                .validator(thread_count_validator)
                .help("Maximum number of outstanding IOs per thread.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("operations")
                .short("n")
                .long("operations")
                .possible_values(&TargetOps::friendly_names())
                .default_value(&target_operations_default_str)
                .help(
                    "Types of operations to generate load for. Not all operations \
                     are allowed for all targets",
                )
                .takes_value(true)
                .use_delimiter(true)
                .multiple(true),
        )
        .arg(
            Arg::with_name("target_type")
                .short("p")
                .long("target_type")
                .possible_values(&AvailableTargets::friendly_names()[..])
                .default_value(&target_type_default_str)
                .help("Maximum number of outstanding IOs per thread.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("sequential")
                .short("s")
                .long("sequential")
                .possible_values(&["true", "false"])
                .default_value(&sequential_default_str)
                .help("Maximum number of outstanding IOs per thread.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("output_config_file")
                .short("o")
                .long("output_config_file")
                .value_name("FILE")
                .default_value(&output_config_file_default_str)
                .help("Maximum number of outstanding IOs per thread.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("target")
                .short("t")
                .long("target")
                .value_name("FILE")
                .required(true)
                .help("Maximum number of outstanding IOs per thread.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("log_ftrace")
                .short("f")
                .long("log_ftrace")
                .possible_values(&["true", "false"])
                .default_value(&log_ftrace_default_str)
                .help("If true, generates ftrace events on IO completion.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("cleanup")
                .short("u")
                .long("cleanup")
                .possible_values(&["true", "false"])
                .default_value(&cleanup_default_str)
                .help("If true, deletes all the temporary files created during run.")
                .takes_value(true),
        )
        .get_matches_from(iter);

    let mut args = ParseArgs {
        queue_depth: matches.value_of("queue_depth").unwrap().parse::<usize>().unwrap(),
        block_size: matches.value_of("block_size").unwrap().parse::<u64>().unwrap(),
        max_io_size: matches.value_of("max_io_size").unwrap().parse::<u64>().unwrap(),
        align: matches.value_of("align").unwrap().parse::<bool>().unwrap(),
        max_io_count: matches.value_of("max_io_count").unwrap().parse::<u64>().unwrap(),
        target_length: matches.value_of("target_length").unwrap().parse::<u64>().unwrap(),
        thread_count: matches.value_of("thread_count").unwrap().parse::<usize>().unwrap(),
        target_type: AvailableTargets::friendly_name_to_value(
            matches.value_of("target_type").unwrap(),
        )
        .unwrap(),
        operations: Default::default(),
        sequential: matches.value_of("sequential").unwrap().parse::<bool>().unwrap(),
        output_config_file: matches.value_of("output_config_file").unwrap().to_string(),
        target: matches.value_of("target").unwrap().to_string(),
        log_ftrace: matches.value_of("log_ftrace").unwrap().parse::<bool>().unwrap(),
        cleanup: matches.value_of("cleanup").unwrap().parse::<bool>().unwrap(),
    };

    if args.log_ftrace && args.block_size > 8192 {
        return Err(Error::LargeBlockSizeWithLogFtrace);
    }

    args.operations = target_operations_validator(
        args.target_type,
        &matches.values_of("operations").unwrap().collect::<Vec<_>>(),
    )?;

    Ok(args)
}

pub fn parse() -> Result<ParseArgs, Error> {
    parse_from(env::args_os())
}

#[cfg(test)]
mod tests {
    use {
        super::{parse_from, Error},
        crate::args,
        crate::common_operations::allowed_ops,
        crate::target::AvailableTargets,
    };

    #[test]
    fn queue_depth_validator_test_default() {
        assert!(args::queue_depth_validator(args::QUEUE_DEPTH_DEFAULT.to_string()).is_ok());
    }

    #[test]
    fn queue_depth_validator_test_out_of_range() {
        assert!(
            args::queue_depth_validator((args::QUEUE_DEPTH_RANGE.end() + 1).to_string()).is_err()
        );
    }

    #[test]
    fn block_size_validator_test_default() {
        assert!(args::block_size_validator(args::BLOCK_SIZE_DEFAULT.to_string()).is_ok());
    }

    #[test]
    fn block_size_validator_test_out_of_range() {
        assert!(args::block_size_validator((args::BLOCK_SIZE_RANGE.end() + 1).to_string()).is_err());
    }

    #[test]
    fn max_io_size_validator_test_default() {
        assert!(args::max_io_size_validator(args::MAX_IO_SIZE_DEFAULT.to_string()).is_ok());
    }

    #[test]
    fn max_io_size_validator_test_out_of_range() {
        assert!(
            args::max_io_size_validator((args::MAX_IO_SIZE_RANGE.end() + 1).to_string()).is_err()
        );
    }

    #[test]
    fn max_io_count_validator_test_default() {
        assert!(args::max_io_count_validator(args::MAX_IO_COUNT_DEFAULT.to_string()).is_ok());
    }

    #[test]
    fn max_io_count_validator_test_out_of_range() {
        assert!(
            args::max_io_count_validator((args::MAX_IO_COUNT_RANGE.end() + 1).to_string()).is_err()
        );
    }

    #[test]
    fn thread_count_validator_test_default() {
        assert!(args::thread_count_validator(args::THREAD_COUNT_DEFAULT.to_string()).is_ok());
    }

    #[test]
    fn thread_count_validator_test_out_of_range() {
        assert!(
            args::thread_count_validator((args::THREAD_COUNT_RANGE.end() + 1).to_string()).is_err()
        );
    }

    #[test]
    fn target_operations_validator_test_valid_inputs() {
        let allowed_ops = allowed_ops(AvailableTargets::FileTarget);

        // We know that "write" is allowed for files. Input "write" to the
        // function and expect success.
        assert_eq!(allowed_ops.enabled("write"), true);

        assert!(
            args::target_operations_validator(AvailableTargets::FileTarget, &vec!["write"]).is_ok()
        );
        assert!(
            args::target_operations_validator(AvailableTargets::FileTarget, &vec!["read"]).is_ok()
        );
    }

    #[test]
    fn target_operations_validator_test_invalid_input_nonexistant_operation() {
        let ret = args::target_operations_validator(AvailableTargets::FileTarget, &vec!["hello"]);
        assert!(ret.is_err());
        assert_eq!(ret.err(), Some(args::Error::OperationNotSupported));
    }

    #[test]
    fn target_operations_validator_test_invalid_input_disallowed_operation() {
        let allowed_ops = allowed_ops(AvailableTargets::FileTarget);

        // We know that "open" is not *yet* allowed for files. Input "open" to the
        // function and expect success.
        assert_eq!(allowed_ops.enabled("open"), false);

        assert!(
            args::target_operations_validator(AvailableTargets::FileTarget, &vec!["open"]).is_err()
        );
    }

    #[test]
    fn test_block_size_with_log_ftrace() {
        let arg_vec =
            vec!["odu", "--log_ftrace=true", "--block_size=8193", "--target=/tmp/abc.xyz"];
        assert_eq!(parse_from(arg_vec).unwrap_err(), Error::LargeBlockSizeWithLogFtrace);

        let arg_vec =
            vec!["odu", "--log_ftrace=true", "--block_size=8192", "--target=/tmp/abc.xyz"];
        assert!(parse_from(arg_vec).is_ok());

        let arg_vec = vec!["odu", "--log_ftrace=true", "--block_size=200", "--target=/tmp/abc.xyz"];
        assert!(parse_from(arg_vec).is_ok());
    }
}
