// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Derive macros that generates both a fuzz target for use with `cargo fuzz`, and a property test
//! (via `quickcheck` or `proptest`) for use with `cargo test`.
//!
//! The reason for having both is that property testing allows for quick iteration to make sure the
//! test works, and can be checked in presubmit CI, while fuzzing can test the input space more
//! exhaustively and run continuously.
//!
//! # Example
//!
//! ```no_run
//! #![cfg_attr(fuzzing, no_main)]
//!
//! #[derive_fuzztest::fuzztest]
//! fn transitive_ord(a: u32, b: u32, c: u32) {
//!     if a >= b && b >= c {
//!         assert!(a >= c);
//!     }
//!     if a <= b && b <= c {
//!         assert!(a <= c);
//!     }
//! }
//!
//! #[test]
//! fn additional_test_here() {
//!     /* ... */
//! }
//! ```
//!
//! # Usage
//!
//!
//! Run the generated property tests
//! ```sh
//! cargo test
//! ```
//!
//! Run continuous fuzzing
//! ```sh
//! cargo +nightly fuzz run <binary name>
//! ```
//!
//! # Crate structure
//!
//! If you use `#[fuzz]` or `#[fuzztest]`, the fuzz target imposes the following requirements:
//!
//! * The target must be in a separate `[[bin]]` target that only contains a single fuzz target.
//! * The crate containing the bin target has `[package.metadata] cargo-fuzz = true`
//! * The bin target is annotated with `#![cfg_attr(fuzzing, no_main)]`
//!
//! The recommended structure for your crate `foo` is to put your tests under `foo/fuzz/src/bin`:
//!
//! ```text
//! foo
//! ├── fuzz
//! │   ├── src
//! │   │   └── bin
//! │   │       └── fuzz_target_1.rs
//! │   └── Cargo.toml
//! ├── src
//! │   └── [project source]
//! └── Cargo.toml
//! ```
//!
//! This is different from the default structure generated by `cargo fuzz init` or `cargo fuzz add`
//! so that we can take advantage of [target
//! auto-discovery](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#target-auto-discovery).
//! If you prefer, the default structure generated by `cargo fuzz` can also work, but make sure you
//! remove `test = false` from the generated target in `Cargo.toml`.
//!
//! You will also need to declare a dependency on the `libfuzzer-sys` crate, but only if fuzzing is
//! requested:
//!
//! ```toml
//! [target.'cfg(fuzzing)'.dependencies]
//! libfuzzer-sys = "*"
//! ```
//!
//! (The reason for this conditional dependency is that `libfuzzer-sys` injects a main function to
//! the resulting binary, and there will be linking failures if we link that in without defining a
//! corresponding `fuzz_target`.)
//!
//! # Features
//!
//! * `quickcheck` (default) — Enable generation of
//!   [`quickcheck`](https://docs.rs/quickcheck/latest/quickcheck/) property tests.
//! * `proptest` — Enable generation of [`proptest`](https://docs.rs/proptest/latest/proptest/)
//!   property tests.
//!
//! #### See also
//! * [Announcing Better Support for Fuzzing with Structured Inputs in
//!   Rust](https://fitzgeraldnick.com/2020/01/16/better-support-for-fuzzing-structured-inputs-in-rust.html#how-is-all-this-different-from-quickcheck-and-proptest)
//! * [Bridging Fuzzing and Property
//!   Testing](https://blog.yoshuawuyts.com/bridging-fuzzing-and-property-testing/)

pub use derive_fuzztest_macro::{fuzz, fuzztest, proptest};

#[doc(hidden)]
pub mod reexport {
    #[cfg(feature = "proptest")]
    pub use proptest;
    #[cfg(feature = "proptest")]
    pub use proptest_arbitrary_interop;
    #[cfg(feature = "quickcheck")]
    pub use quickcheck;
}

#[cfg(feature = "quickcheck")]
#[doc(hidden)]
pub mod arbitrary_bridge {

    /// Wrapper type that allows `arbitrary::Arbitrary` to be used as `quickcheck::Arbitrary`
    #[derive(Debug, Clone)]
    pub struct ArbitraryAdapter<T: for<'a> arbitrary::Arbitrary<'a>>(
        pub Result<T, arbitrary::Error>,
    );

    impl<T> quickcheck::Arbitrary for ArbitraryAdapter<T>
    where
        T: for<'a> arbitrary::Arbitrary<'a> + Clone + 'static,
    {
        fn arbitrary(g: &mut quickcheck::Gen) -> Self {
            let bytes = Vec::<u8>::arbitrary(g);
            let mut unstructured = arbitrary::Unstructured::new(&bytes);
            Self(T::arbitrary(&mut unstructured))
        }
    }
}
