use regex::internal::ExecBuilder;

/// Given a regex, check if all of the backends produce the same
/// results on a number of different inputs.
///
/// For now this just throws quickcheck at the problem, which
/// is not very good because it only really tests half of the
/// problem space. It is pretty unlikely that a random string
/// will match any given regex, so this will probably just
/// be checking that the different backends fail in the same
/// way. This is still worthwhile to test, but is definitely not
/// the whole story.
///
/// TODO(ethan): In order to cover the other half of the problem
/// space, we should generate a random matching string by inspecting
/// the AST of the input regex. The right way to do this probably
/// involves adding a custom Arbitrary instance around a couple
/// of newtypes. That way we can respect the quickcheck size hinting
/// and shrinking and whatnot.
pub fn backends_are_consistent(re: &str) -> Result<u64, String> {
    let standard_backends = vec![
        (
            "bounded_backtracking_re",
            ExecBuilder::new(re)
                .bounded_backtracking()
                .build()
                .map(|exec| exec.into_regex())
                .map_err(|err| format!("{}", err))?,
        ),
        (
            "pikevm_re",
            ExecBuilder::new(re)
                .nfa()
                .build()
                .map(|exec| exec.into_regex())
                .map_err(|err| format!("{}", err))?,
        ),
        (
            "default_re",
            ExecBuilder::new(re)
                .build()
                .map(|exec| exec.into_regex())
                .map_err(|err| format!("{}", err))?,
        ),
    ];

    let utf8bytes_backends = vec![
        (
            "bounded_backtracking_utf8bytes_re",
            ExecBuilder::new(re)
                .bounded_backtracking()
                .bytes(true)
                .build()
                .map(|exec| exec.into_regex())
                .map_err(|err| format!("{}", err))?,
        ),
        (
            "pikevm_utf8bytes_re",
            ExecBuilder::new(re)
                .nfa()
                .bytes(true)
                .build()
                .map(|exec| exec.into_regex())
                .map_err(|err| format!("{}", err))?,
        ),
        (
            "default_utf8bytes_re",
            ExecBuilder::new(re)
                .bytes(true)
                .build()
                .map(|exec| exec.into_regex())
                .map_err(|err| format!("{}", err))?,
        ),
    ];

    let bytes_backends = vec![
        (
            "bounded_backtracking_bytes_re",
            ExecBuilder::new(re)
                .bounded_backtracking()
                .only_utf8(false)
                .build()
                .map(|exec| exec.into_byte_regex())
                .map_err(|err| format!("{}", err))?,
        ),
        (
            "pikevm_bytes_re",
            ExecBuilder::new(re)
                .nfa()
                .only_utf8(false)
                .build()
                .map(|exec| exec.into_byte_regex())
                .map_err(|err| format!("{}", err))?,
        ),
        (
            "default_bytes_re",
            ExecBuilder::new(re)
                .only_utf8(false)
                .build()
                .map(|exec| exec.into_byte_regex())
                .map_err(|err| format!("{}", err))?,
        ),
    ];

    Ok(string_checker::check_backends(&standard_backends)?
        + string_checker::check_backends(&utf8bytes_backends)?
        + bytes_checker::check_backends(&bytes_backends)?)
}

//
// A consistency checker parameterized by the input type (&str or &[u8]).
//

macro_rules! checker {
    ($module_name:ident, $regex_type:path, $mk_input:expr) => {
        mod $module_name {
            use quickcheck;
            use quickcheck::{Arbitrary, TestResult};

            pub fn check_backends(
                backends: &[(&str, $regex_type)],
            ) -> Result<u64, String> {
                let mut total_passed = 0;
                for regex in backends[1..].iter() {
                    total_passed += quickcheck_regex_eq(&backends[0], regex)?;
                }

                Ok(total_passed)
            }

            fn quickcheck_regex_eq(
                &(name1, ref re1): &(&str, $regex_type),
                &(name2, ref re2): &(&str, $regex_type),
            ) -> Result<u64, String> {
                quickcheck::QuickCheck::new()
                    .quicktest(RegexEqualityTest::new(
                        re1.clone(),
                        re2.clone(),
                    ))
                    .map_err(|err| {
                        format!(
                            "{}(/{}/) and {}(/{}/) are inconsistent.\
                             QuickCheck Err: {:?}",
                            name1, re1, name2, re2, err
                        )
                    })
            }

            struct RegexEqualityTest {
                re1: $regex_type,
                re2: $regex_type,
            }
            impl RegexEqualityTest {
                fn new(re1: $regex_type, re2: $regex_type) -> Self {
                    RegexEqualityTest { re1: re1, re2: re2 }
                }
            }

            impl quickcheck::Testable for RegexEqualityTest {
                fn result<G: quickcheck::Gen>(
                    &self,
                    gen: &mut G,
                ) -> TestResult {
                    let input = $mk_input(gen);
                    let input = &input;

                    if self.re1.find(&input) != self.re2.find(input) {
                        return TestResult::error(format!(
                            "find mismatch input={:?}",
                            input
                        ));
                    }

                    let cap1 = self.re1.captures(input);
                    let cap2 = self.re2.captures(input);
                    match (cap1, cap2) {
                        (None, None) => {}
                        (Some(cap1), Some(cap2)) => {
                            for (c1, c2) in cap1.iter().zip(cap2.iter()) {
                                if c1 != c2 {
                                    return TestResult::error(format!(
                                        "captures mismatch input={:?}",
                                        input
                                    ));
                                }
                            }
                        }
                        _ => {
                            return TestResult::error(format!(
                                "captures mismatch input={:?}",
                                input
                            ))
                        }
                    }

                    let fi1 = self.re1.find_iter(input);
                    let fi2 = self.re2.find_iter(input);
                    for (m1, m2) in fi1.zip(fi2) {
                        if m1 != m2 {
                            return TestResult::error(format!(
                                "find_iter mismatch input={:?}",
                                input
                            ));
                        }
                    }

                    let ci1 = self.re1.captures_iter(input);
                    let ci2 = self.re2.captures_iter(input);
                    for (cap1, cap2) in ci1.zip(ci2) {
                        for (c1, c2) in cap1.iter().zip(cap2.iter()) {
                            if c1 != c2 {
                                return TestResult::error(format!(
                                    "captures_iter mismatch input={:?}",
                                    input
                                ));
                            }
                        }
                    }

                    let s1 = self.re1.split(input);
                    let s2 = self.re2.split(input);
                    for (chunk1, chunk2) in s1.zip(s2) {
                        if chunk1 != chunk2 {
                            return TestResult::error(format!(
                                "split mismatch input={:?}",
                                input
                            ));
                        }
                    }

                    TestResult::from_bool(true)
                }
            }
        } // mod
    }; // rule case
} // macro_rules!

checker!(string_checker, ::regex::Regex, |gen| String::arbitrary(gen));
checker!(bytes_checker, ::regex::bytes::Regex, |gen| Vec::<u8>::arbitrary(
    gen
));
