//-
// Copyright 2017 Jason Lingle
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Modified versions of the normal strategy combinators which take specialised
//! traits instead of normal functions.
//!
//! This entire module is strictly a workaround until
//! <https://github.com/rust-lang/rfcs/pull/1522> and
//! <https://github.com/rust-lang/rfcs/pull/2071> are available in stable. It
//! allows naming types built on the combinators without resorting to dynamic
//! dispatch or causing `Arc` to allocate space for a function pointer.
//!
//! External code is discouraged from using this module directly. It is
//! deliberately not exposed in a convenient way (i.e., via the `Strategy`
//! trait itself), but is nonetheless exposed since external trait implementors
//! may face the same issues.
//!
//! **This module is subject to removal at some point after the language
//! features linked above become stable.**

use crate::std_facade::fmt;

use crate::strategy::traits::*;
use crate::test_runner::*;

//==============================================================================
// Filter
//==============================================================================

/// Essentially `Fn (&T) -> bool`.
pub trait FilterFn<T> {
    /// Test whether `t` passes the filter.
    fn apply(&self, t: &T) -> bool;
}

/// Static version of `strategy::Filter`.
#[derive(Clone)]
#[must_use = "strategies do nothing unless used"]
pub struct Filter<S, F> {
    source: S,
    whence: Reason,
    fun: F,
}

impl<S, F> Filter<S, F> {
    /// Adapt strategy `source` to reject values which do not pass `filter`,
    /// using `whence` as the reported reason/location.
    pub fn new(source: S, whence: Reason, filter: F) -> Self {
        // NOTE: We don't use universal quantification R: Into<Reason>
        // since the module is not conviniently exposed.
        Filter { source, whence, fun: filter }
    }
}

impl<S : fmt::Debug, F> fmt::Debug for Filter<S, F> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Filter")
            .field("source", &self.source)
            .field("whence", &self.whence)
            .field("fun", &"<function>")
            .finish()
    }
}

impl<S : Strategy,
     F : FilterFn<S::Value> + Clone>
Strategy for Filter<S, F> {
    type Tree = Filter<S::Tree, F>;
    type Value = S::Value;

    fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
        loop {
            let val = self.source.new_tree(runner)?;
            if !self.fun.apply(&val.current()) {
                runner.reject_local(self.whence.clone())?;
            } else {
                return Ok(Filter {
                    source: val,
                    whence: "unused".into(),
                    fun: self.fun.clone(),
                })
            }
        }
    }
}

impl<S : ValueTree, F : FilterFn<S::Value>> Filter<S, F> {
    fn ensure_acceptable(&mut self) {
        while !self.fun.apply(&self.source.current()) {
            if !self.source.complicate() {
                panic!("Unable to complicate filtered strategy \
                        back into acceptable value");
            }
        }
    }
}

impl<S : ValueTree, F : FilterFn<S::Value>> ValueTree for Filter<S, F> {
    type Value = S::Value;

    fn current(&self) -> S::Value {
        self.source.current()
    }

    fn simplify(&mut self) -> bool {
        if self.source.simplify() {
            self.ensure_acceptable();
            true
        } else {
            false
        }
    }

    fn complicate(&mut self) -> bool {
        if self.source.complicate() {
            self.ensure_acceptable();
            true
        } else {
            false
        }
    }
}

//==============================================================================
// Map
//==============================================================================

/// Essentially `Fn (T) -> Output`.
pub trait MapFn<T> {
    #[allow(missing_docs)]
    type Output : fmt::Debug;

    /// Map `T` to `Output`.
    fn apply(&self, t: T) -> Self::Output;
}

/// Static version of `strategy::Map`.
#[derive(Clone)]
#[must_use = "strategies do nothing unless used"]
pub struct Map<S, F> {
    source: S,
    fun: F,
}

impl<S, F> Map<S, F> {
    /// Adapt strategy `source` by applying `fun` to values it produces.
    pub fn new(source: S, fun: F) -> Self {
        Map { source, fun }
    }
}

impl<S : fmt::Debug, F> fmt::Debug for Map<S, F> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Map")
            .field("source", &self.source)
            .field("fun", &"<function>")
            .finish()
    }
}

impl<S : Strategy, F : Clone + MapFn<S::Value>> Strategy for Map<S, F> {
    type Tree = Map<S::Tree, F>;
    type Value = F::Output;

    fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
        self.source.new_tree(runner).map(
            |v| Map { source: v, fun: self.fun.clone() })
    }
}

impl<S : ValueTree, F : MapFn<S::Value>>
ValueTree for Map<S, F> {
    type Value = F::Output;

    fn current(&self) -> F::Output {
        self.fun.apply(self.source.current())
    }

    fn simplify(&mut self) -> bool {
        self.source.simplify()
    }

    fn complicate(&mut self) -> bool {
        self.source.complicate()
    }
}

impl<I, O: fmt::Debug> MapFn<I> for fn(I) -> O {
    type Output = O;
    fn apply(&self, x: I) -> Self::Output { self(x) }
}

pub(crate) fn static_map<S: Strategy, O: fmt::Debug>
    (strat: S, fun: fn(S::Value) -> O)
    -> Map<S, fn(S::Value) -> O> {
    Map::new(strat, fun)
}

//==============================================================================
// Tests
//==============================================================================

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

    #[test]
    fn test_static_filter() {
        #[derive(Clone, Copy, Debug)]
        struct MyFilter;
        impl FilterFn<i32> for MyFilter {
            fn apply(&self, &v: &i32) -> bool { 0 == v % 3 }
        }

        let input = Filter::new(0..256, "%3".into(), MyFilter);

        for _ in 0..256 {
            let mut runner = TestRunner::default();
            let mut case = input.new_tree(&mut runner).unwrap();

            assert!(0 == case.current() % 3);

            while case.simplify() {
                assert!(0 == case.current() % 3);
            }
            assert!(0 == case.current() % 3);
        }
    }

    #[test]
    fn test_static_map() {
        #[derive(Clone, Copy, Debug)]
        struct MyMap;
        impl MapFn<i32> for MyMap {
            type Output = i32;
            fn apply(&self, v: i32) -> i32 { v * 2 }
        }

        let input = Map::new(0..10, MyMap);

        TestRunner::default()
            .run(&input, |v| {
                assert!(0 == v % 2);
                Ok(())
            }).unwrap();
    }
}
