#![allow(deprecated)]

use crate::analysis;
use crate::connection::OutgoingMessage;
use crate::measurement::{Measurement, WallTime};
use crate::report::{BenchmarkId, Report, ReportContext};
use crate::routine::{Function, Routine};
use crate::{Bencher, Criterion, DurationExt, Mode, PlotConfiguration, SamplingMode, Throughput};
use std::cell::RefCell;
use std::fmt::Debug;
use std::marker::Sized;
use std::time::Duration;

// TODO: Move the benchmark config stuff to a separate module for easier use.

/// Struct containing all of the configuration options for a benchmark.
pub struct BenchmarkConfig {
    pub confidence_level: f64,
    pub measurement_time: Duration,
    pub noise_threshold: f64,
    pub nresamples: usize,
    pub sample_size: usize,
    pub significance_level: f64,
    pub warm_up_time: Duration,
    pub sampling_mode: SamplingMode,
}

/// Struct representing a partially-complete per-benchmark configuration.
#[derive(Clone)]
pub(crate) struct PartialBenchmarkConfig {
    pub(crate) confidence_level: Option<f64>,
    pub(crate) measurement_time: Option<Duration>,
    pub(crate) noise_threshold: Option<f64>,
    pub(crate) nresamples: Option<usize>,
    pub(crate) sample_size: Option<usize>,
    pub(crate) significance_level: Option<f64>,
    pub(crate) warm_up_time: Option<Duration>,
    pub(crate) sampling_mode: Option<SamplingMode>,
    pub(crate) plot_config: PlotConfiguration,
}

impl Default for PartialBenchmarkConfig {
    fn default() -> Self {
        PartialBenchmarkConfig {
            confidence_level: None,
            measurement_time: None,
            noise_threshold: None,
            nresamples: None,
            sample_size: None,
            significance_level: None,
            warm_up_time: None,
            plot_config: PlotConfiguration::default(),
            sampling_mode: None,
        }
    }
}

impl PartialBenchmarkConfig {
    pub(crate) fn to_complete(&self, defaults: &BenchmarkConfig) -> BenchmarkConfig {
        BenchmarkConfig {
            confidence_level: self.confidence_level.unwrap_or(defaults.confidence_level),
            measurement_time: self.measurement_time.unwrap_or(defaults.measurement_time),
            noise_threshold: self.noise_threshold.unwrap_or(defaults.noise_threshold),
            nresamples: self.nresamples.unwrap_or(defaults.nresamples),
            sample_size: self.sample_size.unwrap_or(defaults.sample_size),
            significance_level: self
                .significance_level
                .unwrap_or(defaults.significance_level),
            warm_up_time: self.warm_up_time.unwrap_or(defaults.warm_up_time),
            sampling_mode: self.sampling_mode.unwrap_or(defaults.sampling_mode),
        }
    }
}

pub(crate) struct NamedRoutine<T, M: Measurement = WallTime> {
    pub id: String,
    pub(crate) f: Box<RefCell<dyn Routine<M, T>>>,
}

/// Structure representing a benchmark (or group of benchmarks)
/// which take one parameter.
#[doc(hidden)]
#[deprecated(since = "0.3.4", note = "Please use BenchmarkGroups instead.")]
pub struct ParameterizedBenchmark<T: Debug, M: Measurement = WallTime> {
    config: PartialBenchmarkConfig,
    values: Vec<T>,
    routines: Vec<NamedRoutine<T, M>>,
    throughput: Option<Box<dyn Fn(&T) -> Throughput>>,
}

/// Structure representing a benchmark (or group of benchmarks)
/// which takes no parameters.
#[doc(hidden)]
#[deprecated(since = "0.3.4", note = "Please use BenchmarkGroups instead.")]
pub struct Benchmark<M: Measurement = WallTime> {
    config: PartialBenchmarkConfig,
    routines: Vec<NamedRoutine<(), M>>,
    throughput: Option<Throughput>,
}

/// Common trait for `Benchmark` and `ParameterizedBenchmark`. Not intended to be
/// used outside of Criterion.rs.
#[doc(hidden)]
pub trait BenchmarkDefinition<M: Measurement = WallTime>: Sized {
    #[doc(hidden)]
    fn run(self, group_id: &str, c: &mut Criterion<M>);
}

macro_rules! benchmark_config {
    ($type:tt) => {
        /// Changes the size of the sample for this benchmark
        ///
        /// A bigger sample should yield more accurate results if paired with a sufficiently large
        /// measurement time.
        ///
        /// Sample size must be at least 10.
        ///
        /// # Panics
        ///
        /// Panics if n < 10.
        pub fn sample_size(mut self, n: usize) -> Self {
            assert!(n >= 10);

            self.config.sample_size = Some(n);
            self
        }

        /// Changes the warm up time for this benchmark
        ///
        /// # Panics
        ///
        /// Panics if the input duration is zero
        pub fn warm_up_time(mut self, dur: Duration) -> Self {
            assert!(dur.to_nanos() > 0);

            self.config.warm_up_time = Some(dur);
            self
        }

        /// Changes the target measurement time for this benchmark. Criterion will attempt
        /// to spend approximately this amount of time measuring the benchmark.
        /// With a longer time, the measurement will become more resilient to transitory peak loads
        /// caused by external programs.
        ///
        /// # Panics
        ///
        /// Panics if the input duration in zero
        pub fn measurement_time(mut self, dur: Duration) -> Self {
            assert!(dur.to_nanos() > 0);

            self.config.measurement_time = Some(dur);
            self
        }

        /// Changes the number of resamples for this benchmark
        ///
        /// Number of resamples to use for the
        /// [bootstrap](http://en.wikipedia.org/wiki/Bootstrapping_(statistics)#Case_resampling)
        ///
        /// A larger number of resamples reduces the random sampling errors, which are inherent to the
        /// bootstrap method, but also increases the analysis time.
        ///
        /// # Panics
        ///
        /// Panics if the number of resamples is set to zero
        pub fn nresamples(mut self, n: usize) -> Self {
            assert!(n > 0);
            if n <= 1000 {
                println!("\nWarning: It is not recommended to reduce nresamples below 1000.");
            }

            self.config.nresamples = Some(n);
            self
        }

        /// Changes the default noise threshold for this benchmark. The noise threshold
        /// is used to filter out small changes in performance, even if they are statistically
        /// significant. Sometimes benchmarking the same code twice will result in small but
        /// statistically significant differences solely because of noise. This provides a way to filter
        /// out some of these false positives at the cost of making it harder to detect small changes
        /// to the true performance of the benchmark.
        ///
        /// The default is 0.01, meaning that changes smaller than 1% will be ignored.
        ///
        /// # Panics
        ///
        /// Panics if the threshold is set to a negative value
        pub fn noise_threshold(mut self, threshold: f64) -> Self {
            assert!(threshold >= 0.0);

            self.config.noise_threshold = Some(threshold);
            self
        }

        /// Changes the default confidence level for this benchmark. The confidence
        /// level is the desired probability that the true runtime lies within the estimated
        /// [confidence interval](https://en.wikipedia.org/wiki/Confidence_interval). The default is
        /// 0.95, meaning that the confidence interval should capture the true value 95% of the time.
        ///
        /// # Panics
        ///
        /// Panics if the confidence level is set to a value outside the `(0, 1)` range
        pub fn confidence_level(mut self, cl: f64) -> Self {
            assert!(cl > 0.0 && cl < 1.0);
            if cl < 0.5 {
                println!("\nWarning: It is not recommended to reduce confidence level below 0.5.");
            }

            self.config.confidence_level = Some(cl);
            self
        }

        /// Changes the default [significance level](https://en.wikipedia.org/wiki/Statistical_significance)
        /// for this benchmark. This is used to perform a
        /// [hypothesis test](https://en.wikipedia.org/wiki/Statistical_hypothesis_testing) to see if
        /// the measurements from this run are different from the measured performance of the last run.
        /// The significance level is the desired probability that two measurements of identical code
        /// will be considered 'different' due to noise in the measurements. The default value is 0.05,
        /// meaning that approximately 5% of identical benchmarks will register as different due to
        /// noise.
        ///
        /// This presents a trade-off. By setting the significance level closer to 0.0, you can increase
        /// the statistical robustness against noise, but it also weakens Criterion.rs' ability to
        /// detect small but real changes in the performance. By setting the significance level
        /// closer to 1.0, Criterion.rs will be more able to detect small true changes, but will also
        /// report more spurious differences.
        ///
        /// See also the noise threshold setting.
        ///
        /// # Panics
        ///
        /// Panics if the significance level is set to a value outside the `(0, 1)` range
        pub fn significance_level(mut self, sl: f64) -> Self {
            assert!(sl > 0.0 && sl < 1.0);

            self.config.significance_level = Some(sl);
            self
        }

        /// Changes the plot configuration for this benchmark.
        pub fn plot_config(mut self, new_config: PlotConfiguration) -> Self {
            self.config.plot_config = new_config;
            self
        }

        /// Changes the sampling mode for this benchmark.
        pub fn sampling_mode(mut self, new_mode: SamplingMode) -> Self {
            self.config.sampling_mode = Some(new_mode);
            self
        }
    };
}

impl<M> Benchmark<M>
where
    M: Measurement + 'static,
{
    benchmark_config!(Benchmark);

    /// Create a new benchmark group and adds the given function to it.
    ///
    /// # Example
    ///
    /// ```rust
    /// # #[macro_use] extern crate criterion;
    /// # use criterion::*;
    ///
    /// fn bench(c: &mut Criterion) {
    ///     // One-time setup goes here
    ///     c.bench(
    ///         "my_group",
    ///         Benchmark::new("my_function", |b| b.iter(|| {
    ///             // Code to benchmark goes here
    ///         })),
    ///     );
    /// }
    ///
    /// criterion_group!(benches, bench);
    /// criterion_main!(benches);
    /// ```
    pub fn new<S, F>(id: S, f: F) -> Benchmark<M>
    where
        S: Into<String>,
        F: FnMut(&mut Bencher<'_, M>) + 'static,
    {
        Benchmark {
            config: PartialBenchmarkConfig::default(),
            routines: vec![],
            throughput: None,
        }
        .with_function(id, f)
    }

    /// Add a function to the benchmark group.
    pub fn with_function<S, F>(mut self, id: S, mut f: F) -> Benchmark<M>
    where
        S: Into<String>,
        F: FnMut(&mut Bencher<'_, M>) + 'static,
    {
        let routine = NamedRoutine {
            id: id.into(),
            f: Box::new(RefCell::new(Function::new(move |b, _| f(b)))),
        };
        self.routines.push(routine);
        self
    }

    /// Set the input size for this benchmark group. Used for reporting the
    /// throughput.
    pub fn throughput(mut self, throughput: Throughput) -> Benchmark<M> {
        self.throughput = Some(throughput);
        self
    }
}

impl<M: Measurement> BenchmarkDefinition<M> for Benchmark<M> {
    fn run(self, group_id: &str, c: &mut Criterion<M>) {
        let report_context = ReportContext {
            output_directory: c.output_directory.clone(),
            plot_config: self.config.plot_config.clone(),
        };

        let config = self.config.to_complete(&c.config);
        let num_routines = self.routines.len();

        let mut all_ids = vec![];
        let mut any_matched = false;

        if let Some(conn) = &c.connection {
            conn.send(&OutgoingMessage::BeginningBenchmarkGroup { group: group_id })
                .unwrap();
        }

        for routine in self.routines {
            let function_id = if num_routines == 1 && group_id == routine.id {
                None
            } else {
                Some(routine.id)
            };

            let mut id = BenchmarkId::new(
                group_id.to_owned(),
                function_id,
                None,
                self.throughput.clone(),
            );

            id.ensure_directory_name_unique(&c.all_directories);
            c.all_directories.insert(id.as_directory_name().to_owned());
            id.ensure_title_unique(&c.all_titles);
            c.all_titles.insert(id.as_title().to_owned());

            let do_run = c.filter_matches(id.id());
            any_matched |= do_run;

            execute_benchmark(
                do_run,
                &id,
                c,
                &config,
                &mut *routine.f.borrow_mut(),
                &report_context,
                &(),
                self.throughput.clone(),
            );

            all_ids.push(id);
        }

        if let Some(conn) = &c.connection {
            conn.send(&OutgoingMessage::FinishedBenchmarkGroup { group: group_id })
                .unwrap();
            conn.serve_value_formatter(c.measurement.formatter())
                .unwrap();
        }

        if all_ids.len() > 1 && any_matched && c.mode.is_benchmark() {
            c.report
                .summarize(&report_context, &all_ids, c.measurement.formatter());
        }
        if any_matched {
            c.report.group_separator();
        }
    }
}

impl<T, M> ParameterizedBenchmark<T, M>
where
    T: Debug + 'static,
    M: Measurement + 'static,
{
    benchmark_config!(ParameterizedBenchmark);

    pub(crate) fn with_functions(
        functions: Vec<NamedRoutine<T, M>>,
        parameters: Vec<T>,
    ) -> ParameterizedBenchmark<T, M> {
        ParameterizedBenchmark {
            config: PartialBenchmarkConfig::default(),
            values: parameters,
            routines: functions,
            throughput: None,
        }
    }

    /// Create a new parameterized benchmark group and adds the given function
    /// to it.
    /// The function under test must follow the setup - bench - teardown pattern:
    ///
    /// # Example
    ///
    /// ```rust
    /// # #[macro_use] extern crate criterion;
    /// # use criterion::*;
    ///
    /// fn bench(c: &mut Criterion) {
    ///     let parameters = vec![1u64, 2u64, 3u64];
    ///
    ///     // One-time setup goes here
    ///     c.bench(
    ///         "my_group",
    ///         ParameterizedBenchmark::new(
    ///             "my_function",
    ///             |b, param| b.iter(|| {
    ///                 // Code to benchmark using param goes here
    ///             }),
    ///             parameters
    ///         )
    ///     );
    /// }
    ///
    /// criterion_group!(benches, bench);
    /// criterion_main!(benches);
    /// ```
    pub fn new<S, F, I>(id: S, f: F, parameters: I) -> ParameterizedBenchmark<T, M>
    where
        S: Into<String>,
        F: FnMut(&mut Bencher<'_, M>, &T) + 'static,
        I: IntoIterator<Item = T>,
    {
        ParameterizedBenchmark {
            config: PartialBenchmarkConfig::default(),
            values: parameters.into_iter().collect(),
            routines: vec![],
            throughput: None,
        }
        .with_function(id, f)
    }

    /// Add a function to the benchmark group.
    pub fn with_function<S, F>(mut self, id: S, f: F) -> ParameterizedBenchmark<T, M>
    where
        S: Into<String>,
        F: FnMut(&mut Bencher<'_, M>, &T) + 'static,
    {
        let routine = NamedRoutine {
            id: id.into(),
            f: Box::new(RefCell::new(Function::new(f))),
        };
        self.routines.push(routine);
        self
    }

    /// Use the given function to calculate the input size for a given input.
    pub fn throughput<F>(mut self, throughput: F) -> ParameterizedBenchmark<T, M>
    where
        F: Fn(&T) -> Throughput + 'static,
    {
        self.throughput = Some(Box::new(throughput));
        self
    }
}
impl<T, M> BenchmarkDefinition<M> for ParameterizedBenchmark<T, M>
where
    T: Debug + 'static,
    M: Measurement + 'static,
{
    fn run(self, group_id: &str, c: &mut Criterion<M>) {
        let report_context = ReportContext {
            output_directory: c.output_directory.clone(),
            plot_config: self.config.plot_config.clone(),
        };

        let config = self.config.to_complete(&c.config);
        let num_parameters = self.values.len();
        let num_routines = self.routines.len();

        let mut all_ids = vec![];
        let mut any_matched = false;

        if let Some(conn) = &c.connection {
            conn.send(&OutgoingMessage::BeginningBenchmarkGroup { group: group_id })
                .unwrap();
        }

        for routine in self.routines {
            for value in &self.values {
                let function_id = if num_routines == 1 && group_id == routine.id {
                    None
                } else {
                    Some(routine.id.clone())
                };

                let value_str = if num_parameters == 1 {
                    None
                } else {
                    Some(format!("{:?}", value))
                };

                let throughput = self.throughput.as_ref().map(|func| func(value));
                let mut id = BenchmarkId::new(
                    group_id.to_owned(),
                    function_id,
                    value_str,
                    throughput.clone(),
                );

                id.ensure_directory_name_unique(&c.all_directories);
                c.all_directories.insert(id.as_directory_name().to_owned());
                id.ensure_title_unique(&c.all_titles);
                c.all_titles.insert(id.as_title().to_owned());

                let do_run = c.filter_matches(id.id());
                any_matched |= do_run;

                execute_benchmark(
                    do_run,
                    &id,
                    c,
                    &config,
                    &mut *routine.f.borrow_mut(),
                    &report_context,
                    value,
                    throughput,
                );

                all_ids.push(id);
            }
        }

        if let Some(conn) = &c.connection {
            conn.send(&OutgoingMessage::FinishedBenchmarkGroup { group: group_id })
                .unwrap();
            conn.serve_value_formatter(c.measurement.formatter())
                .unwrap();
        }

        if all_ids.len() > 1 && any_matched && c.mode.is_benchmark() {
            c.report
                .summarize(&report_context, &all_ids, c.measurement.formatter());
        }
        if any_matched {
            c.report.group_separator();
        }
    }
}

#[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))]
fn execute_benchmark<T, M>(
    do_run: bool,
    id: &BenchmarkId,
    c: &Criterion<M>,
    config: &BenchmarkConfig,
    routine: &mut dyn Routine<M, T>,
    report_context: &ReportContext,
    parameter: &T,
    throughput: Option<Throughput>,
) where
    T: Debug,
    M: Measurement,
{
    match c.mode {
        Mode::Benchmark => {
            if let Some(conn) = &c.connection {
                if do_run {
                    conn.send(&OutgoingMessage::BeginningBenchmark { id: id.into() })
                        .unwrap();
                } else {
                    conn.send(&OutgoingMessage::SkippingBenchmark { id: id.into() })
                        .unwrap();
                }
            }

            if do_run {
                analysis::common(
                    id,
                    routine,
                    config,
                    c,
                    report_context,
                    parameter,
                    throughput,
                );
            }
        }
        Mode::List => {
            if do_run {
                println!("{}: bench", id);
            }
        }
        Mode::Test => {
            if do_run {
                // In test mode, run the benchmark exactly once, then exit.
                c.report.test_start(id, report_context);
                routine.test(&c.measurement, parameter);
                c.report.test_pass(id, report_context);
            }
        }
        Mode::Profile(duration) => {
            if do_run {
                routine.profile(&c.measurement, id, c, report_context, duration, parameter);
            }
        }
    }
}
