//-
// 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.

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

/// Adaptor for `Strategy` and `ValueTree` which guards `simplify()` and
/// `complicate()` to avoid contract violations.
///
/// This can be used as an intermediate when the caller would otherwise need
/// its own separate state tracking, or as a workaround for a broken
/// `ValueTree` implementation.
///
/// This wrapper specifically has the following effects:
///
/// - Calling `complicate()` before `simplify()` was ever called does nothing
///   and returns `false`.
///
/// - Calling `simplify()` after it has returned `false` and no calls to
///   `complicate()` returned `true` does nothing and returns `false`.
///
/// - Calling `complicate()` after it has returned `false` and no calls to
///   `simplify()` returned `true` does nothing and returns `false`.
///
/// There is also limited functionality to alter the internal state to assist
/// in its usage as a state tracker.
///
/// Wrapping a `Strategy` in `Fuse` simply causes its `ValueTree` to also be
/// wrapped in `Fuse`.
///
/// While this is similar to `std::iter::Fuse`, it is not exposed as a method
/// on `Strategy` since the vast majority of proptest should never need this
/// functionality; it mainly concerns implementors of strategies.
#[derive(Debug, Clone, Copy)]
#[must_use = "strategies do nothing unless used"]
pub struct Fuse<T> {
    inner: T,
    may_simplify: bool,
    may_complicate: bool,
}

impl<T> Fuse<T> {
    /// Wrap the given `T` in `Fuse`.
    pub fn new(inner: T) -> Self {
        Fuse {
            inner,
            may_simplify: true,
            may_complicate: false,
        }
    }
}

impl<T : Strategy> Strategy for Fuse<T> {
    type Tree = Fuse<T::Tree>;
    type Value = T::Value;

    fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
        self.inner.new_tree(runner).map(Fuse::new)
    }
}

impl<T : ValueTree> Fuse<T> {
    /// Return whether a call to `simplify()` may be productive.
    ///
    /// Formally, this is true if one of the following holds:
    ///
    /// - `simplify()` has never been called.
    /// - The most recent call to `simplify()` returned `true`.
    /// - `complicate()` has been called more recently than `simplify()` and
    ///   the last call returned `true`.
    pub fn may_simplify(&self) -> bool {
        self.may_simplify
    }

    /// Disallow any further calls to `simplify()` until a call to
    /// `complicate()` returns `true`.
    pub fn disallow_simplify(&mut self) {
        self.may_simplify = false;
    }

    /// Return whether a call to `complicate()` may be productive.
    ///
    /// Formally, this is true if one of the following holds:
    ///
    /// - The most recent call to `complicate()` returned `true`.
    /// - `simplify()` has been called more recently than `complicate()` and
    ///   the last call returned `true`.
    pub fn may_complicate(&self) -> bool {
        self.may_complicate
    }

    /// Disallow any further calls to `complicate()` until a call to
    /// `simplify()` returns `true`.
    pub fn disallow_complicate(&mut self) {
        self.may_complicate = false;
    }

    /// Prevent any further shrinking operations from occurring.
    pub fn freeze(&mut self) {
        self.disallow_simplify();
        self.disallow_complicate();
    }
}

impl<T : ValueTree> ValueTree for Fuse<T> {
    type Value = T::Value;

    fn current(&self) -> T::Value {
        self.inner.current()
    }

    fn simplify(&mut self) -> bool {
        if self.may_simplify {
            if self.inner.simplify() {
                self.may_complicate = true;
                true
            } else {
                self.may_simplify = false;
                false
            }
        } else {
            false
        }
    }

    fn complicate(&mut self) -> bool {
        if self.may_complicate {
            if self.inner.complicate() {
                self.may_simplify = true;
                true
            } else {
                self.may_complicate = false;
                false
            }
        } else {
            false
        }
    }
}

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

    struct StrictValueTree {
        min: u32,
        curr: u32,
        max: u32,
        ready: bool,
    }

    impl StrictValueTree {
        fn new(start: u32) -> Self {
            StrictValueTree {
                min: 0,
                curr: start,
                max: start,
                ready: false,
            }
        }
    }

    impl ValueTree for StrictValueTree {
        type Value = u32;

        fn current(&self) -> u32 {
            self.curr
        }

        fn simplify(&mut self) -> bool {
            assert!(self.min <= self.curr);
            if self.curr > self.min {
                self.max = self.curr;
                self.curr -= 1;
                self.ready = true;
                true
            } else {
                self.min += 1;
                false
            }
        }

        fn complicate(&mut self) -> bool {
            assert!(self.max >= self.curr);
            assert!(self.ready);
            if self.curr < self.max {
                self.curr += 1;
                true
            } else {
                self.max -= 1;
                false
            }
        }
    }

    #[test]
    fn test_sanity() {
        check_strategy_sanity(Fuse::new(0i32..100i32), None);
    }

    #[test]
    fn guards_bad_transitions() {
        let mut vt = Fuse::new(StrictValueTree::new(5));
        assert!(!vt.complicate());
        assert_eq!(5, vt.current());

        assert!(vt.simplify()); // 0, 4, 5
        assert!(vt.simplify()); // 0, 3, 4
        assert!(vt.simplify()); // 0, 2, 3
        assert!(vt.simplify()); // 0, 1, 2
        assert!(vt.simplify()); // 0, 0, 1
        assert_eq!(0, vt.current());
        assert!(!vt.simplify()); // 1, 0, 1
        assert!(!vt.simplify()); // 1, 0, 1
        assert_eq!(0, vt.current());
        assert!(vt.complicate()); // 1, 1, 1
        assert_eq!(1, vt.current());
        assert!(!vt.complicate()); // 1, 1, 0
        assert!(!vt.complicate()); // 1, 1, 0
        assert_eq!(1, vt.current());
    }
}
