// Copyright 2018 The proptest developers
//
// 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 proptest::prelude::{BoxedStrategy, Strategy, Arbitrary, proptest};
use proptest::string::StrategyFromRegex;
use proptest_derive::Arbitrary;

fn mk_regex() -> &'static str {
    "[0-9][0-9]"
}

// struct:

#[derive(Debug, Arbitrary)]
struct T0 {
    #[proptest(regex = "a+")]
    foo: String,
    #[proptest(regex("b+"))]
    bar: String,
    #[proptest(regex(mk_regex))]
    baz: String,
    #[proptest(regex = "(a|b)+")]
    quux: Vec<u8>,
    #[proptest(
        regex("[abc]+"),
        filter("|c| c.len() < 4")
    )]
    wibble: Vec<u8>,
    #[proptest(regex(mk_regex))]
    wobble: Vec<u8>,
}

#[derive(Debug, Arbitrary)]
struct T1(
    #[proptest(regex = "a+")]
    String,
    #[proptest(regex("b+"))]
    String,
    #[proptest(regex(mk_regex))]
    String,
    #[proptest(regex = "(a|b)+")]
    Vec<u8>,
    #[proptest(
        regex("[abc]+"),
        filter("|c| c.len() < 4")
    )]
    Vec<u8>,
    #[proptest(regex(mk_regex))]
    Vec<u8>,
);

#[derive(Debug, Arbitrary)]
struct T1r(
    #[proptest(regex = r"a+")]
    String,
    #[proptest(regex(r"b+"))]
    String,
    #[proptest(regex(mk_regex))]
    String,
    #[proptest(regex = r"(a|b)+")]
    Vec<u8>,
    #[proptest(
        regex(r"[abc]+"),
        filter("|c| c.len() < 4")
    )]
    Vec<u8>,
    #[proptest(regex(mk_regex))]
    Vec<u8>,
);

// enum:

#[derive(Debug, Arbitrary)]
enum T2 {
    V0 {
        #[proptest(regex = "a+")]
        foo: String,
        #[proptest(regex("b+"))]
        bar: String,
        #[proptest(regex(mk_regex))]
        baz: String,
        #[proptest(regex = "(a|b)+")]
        quux: Vec<u8>,
        #[proptest(
            regex("[abc]+"),
            filter("|c| c.len() < 4")
        )]
        wibble: Vec<u8>,
        #[proptest(regex(mk_regex))]
        wobble: Vec<u8>,
    }
}

#[derive(Debug, Arbitrary)]
enum T3 {
    V0(
        #[proptest(regex = "a+")]
        String,
        #[proptest(regex("b+"))]
        String,
        #[proptest(regex(mk_regex))]
        String,
        #[proptest(regex = "(a|b)+")]
        Vec<u8>,
        #[proptest(
            regex("[abc]+"),
            filter("|c| c.len() < 4")
        )]
        Vec<u8>,
        #[proptest(regex(mk_regex))]
        Vec<u8>,
    )
}

// Show that it works for new types and that `String` | `Vec<u8>` isn't
// hardcoded into the logic:

#[derive(Debug)]
struct NewString(String);

impl StrategyFromRegex for NewString {
    type Strategy = BoxedStrategy<Self>;

    fn from_regex(regex: &str) -> Self::Strategy {
        String::from_regex(regex).prop_map(NewString).boxed()
    }
}

#[derive(Debug, Arbitrary)]
struct T4(#[proptest(regex = "a+")] NewString);

fn check_aplus(x0: String) {
    assert!(x0.chars().count() > 0);
    assert!(x0.chars().all(|c: char| c == 'a'));
}

fn assert_adherence(
    x0: String, x1: String, x2: String,
    y0: Vec<u8>, y1: Vec<u8>, y2: Vec<u8>,
) {
    check_aplus(x0);

    assert!(x1.chars().count() > 0);
    assert!(x1.chars().all(|c: char| c == 'b'));

    assert!(x2.parse::<u8>().unwrap() < 100);

    assert!(y0.len() > 0);
    assert!(y0.iter().all(|c: &u8| [b'a', b'b'].contains(c)));

    assert!(y1.len() > 0 && y1.len() < 4);
    assert!(y1.iter().all(|c: &u8| [b'a', b'b', b'c'].contains(c)));

    assert!(y2.len() > 0);
    let test = y2.iter().all(|c: &u8| if let b'0'..=b'9' = c { true } else { false });
    assert!(test);
}

proptest! {
    #[test]
    fn t0_adhering_to_regex(v: T0) {
        let T0 {
            foo: x0, bar: x1, baz: x2,
            quux: y0, wibble: y1, wobble: y2
        } = v;
        assert_adherence(x0, x1, x2, y0, y1, y2);
    }

    #[test]
    fn t1_adhering_to_regex(v: T1) {
        let T1(x0, x1, x2, y0, y1, y2) = v;
        assert_adherence(x0, x1, x2, y0, y1, y2);
    }

    #[test]
    fn t1_r_adhering_to_regex(v: T1r) {
        let T1r(x0, x1, x2, y0, y1, y2) = v;
        assert_adherence(x0, x1, x2, y0, y1, y2);
    }

    #[test]
    fn t2_adhering_to_regex(v: T2) {
        let T2::V0 {
            foo: x0, bar: x1, baz: x2,
            quux: y0, wibble: y1, wobble: y2
        } = v;
        assert_adherence(x0, x1, x2, y0, y1, y2);
    }

    #[test]
    fn t3_adhering_to_regex(v: T3) {
        let T3::V0(x0, x1, x2, y0, y1, y2) = v;
        assert_adherence(x0, x1, x2, y0, y1, y2);
    }

    #[test]
    fn t4_adhering_to_regex(v: T4) {
        check_aplus((v.0).0);
    }
}

#[test]
fn asserting_arbitrary() {
    fn assert_arbitrary<T: Arbitrary>() {}

    assert_arbitrary::<T0>();
    assert_arbitrary::<T1>();
    assert_arbitrary::<T2>();
    assert_arbitrary::<T3>();
    assert_arbitrary::<T4>();
}
