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

pub mod arbitrary;
pub mod containers;
pub mod range;
pub mod tuple_of;
pub mod utility;
use ::serde::de::DeserializeOwned;
use ::serde::Serialize;

use anyhow;
use anyhow::Context;
use rand::RngExt;

use std::any::Any;
use std::fmt;

pub trait CloneAny: Any {
    fn clone_box(&self) -> Box<dyn CloneAny>;
    fn as_any(&self) -> &dyn Any;
    fn as_mut_any(&mut self) -> &mut dyn Any;
}

impl dyn CloneAny {
    /// Returns `true` if the underlying type is of type `T`
    pub fn is<T: Any>(&self) -> bool {
        self.as_any().is::<T>()
    }

    /// Returns a reference to the concrete value if it is of type `T`, or `None` otherwise.
    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
        self.as_any().downcast_ref::<T>()
    }

    /// Returns a mutable reference to the concrete value if it is of type `T`, or `None` otherwise.
    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
        self.as_mut_any().downcast_mut::<T>()
    }
}

impl<T: Any + Clone> CloneAny for T {
    fn clone_box(&self) -> Box<dyn CloneAny> {
        // Prevent infinite recursion if T is a nested Box type.
        if let Some(boxed) = self.as_any().downcast_ref::<Box<dyn CloneAny>>() {
            return (**boxed).clone_box();
        }
        Box::new(self.clone())
    }

    fn as_any(&self) -> &dyn Any {
        self
    }

    fn as_mut_any(&mut self) -> &mut dyn Any {
        self
    }
}

impl Clone for Box<dyn CloneAny> {
    fn clone(&self) -> Self {
        self.clone_box()
    }
}

/// Type alias for a type-erased corpus value.
pub type GenericCorpusValue = Box<dyn CloneAny>;

/// Type alias for a type-erased user value.
pub type GenericUserValue = Box<dyn CloneAny>;

/// A trait for types that represent a set of values that an input can take.
///
/// Domain types are used to represent the domain of values that a fuzz test input can take
/// throughout the fuzzing process.
/// Domain types are used by the fuzzing engine through the APIs defined in this trait.
///
/// ## Serialization/Deserialization of CorpusValue and UserValue relationship.
///
/// The values drawn from a domain are always of type `CorpusValue`. These values are the
/// internal representation of the value and they are not directly usable by the fuzz property
/// function.
///
/// The `get_user_value` method is used to retrieve the user value from the corpus value. For
/// example, if the domain outputs an `&str` then the CorpusValue could be a `String` and the
/// `get_user_value` method would be used to retrieve the `&str` from the `String`.
///
/// The `parse_corpus` (resp. `serialize_corpus`) method is used deserialize (resp. serialize)
/// the corpus value from (to) a slice of bytes (resp. a vector of bytes).
///
/// ### Relationship diagram
///
/// The methods below are responsible for transforming between `UserValue`, `CorpusValue`, and the
/// serialized representation of `CorpusValue`. Here's a quick overview:
///
/// ```text
///        +-- get_user_value() <---+     +-- parse_corpus() <---+
///        |                        |     |                      |
///        v                        |     v                      |
///   UserValue<'a>               CorpusValue                  &[u8]
///                                       |                      ^
///                                       |                      |
///                                       +-> serialize_corpus() +
/// ```
pub trait Domain {
    /// The type of the values that the domain outputs. This should of the same type as the
    /// parameter of the fuzz property function.
    type UserValue<'user>;
    /// The type of the corpus from which the values of type UserValue are drawn.
    /// For example, if the domain should output an `&str` then the UserValue should be `&str` and
    /// the CorpusValue could the owned data structured that the `&str` points to (eg: String).
    /// The CorpusValue type should implement `serde::Serialize`, `serde::de::DeserializeOwned` and
    /// `Clone`.
    type CorpusValue: Serialize + DeserializeOwned + Clone;

    /// Initializes a new value drawn from the domain.
    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue>;

    /// Mutates the value in `val` to a new value drawn from the domain.
    ///
    /// If `only_shrink` is `true`, then the mutation must not increase the size of the corpus
    /// value. Otherwise, the mutation can both shrink and grow the corpus value.
    fn mutate(
        &mut self,
        val: &mut Self::CorpusValue,
        rng: &mut dyn rand::Rng,
        only_shrink: bool,
    ) -> anyhow::Result<()>;

    /// Retrieves a UserValue from a given CorpusValue.
    ///
    /// This is used to convert the corpus value into the user value that can then be passed to the
    /// fuzz property function.
    fn get_user_value<'a>(
        &self,
        corpus_value: &'a Self::CorpusValue,
    ) -> anyhow::Result<Self::UserValue<'a>>;

    /// Turns a slice of bytes into `CorpusValue`.
    ///
    /// By default, it uses Postcard to deserialize the data.
    fn parse_corpus(&self, data: &[u8]) -> anyhow::Result<Self::CorpusValue> {
        postcard::from_bytes(data).context("Failed to deserialize corpus value from bytes")
    }

    /// Serializes `corpus_value` to a Vec of bytes (ie, Vec<u8>).
    ///
    /// By default, it uses Postcard to serialize the data.
    fn serialize_corpus(&self, corpus_value: &Self::CorpusValue) -> anyhow::Result<Vec<u8>> {
        postcard::to_stdvec(corpus_value).context("Failed to serialize corpus value to bytes")
    }

    /// Converts a user value to a corpus value.
    #[allow(clippy::wrong_self_convention)]
    fn from_value(&self, value: Self::UserValue<'_>) -> anyhow::Result<Self::CorpusValue>;

    /// Validates that a corpus value satisfies the domain's constraints.
    fn validate_corpus_value(&self, _corpus_value: &Self::CorpusValue) -> anyhow::Result<()> {
        Ok(())
    }
}

/// Helper struct that stores seeds and optional lazy seed provider for a domain.
pub struct DomainSeeds<C> {
    seeds: Vec<C>,
    seed_provider: Option<Box<dyn FnOnce() -> Vec<C> + Send + Sync>>,
}

impl<C> Default for DomainSeeds<C> {
    fn default() -> Self {
        Self {
            seeds: Vec::new(),
            seed_provider: None,
        }
    }
}

impl<C> DomainSeeds<C> {
    pub fn new() -> Self {
        Self::default()
    }
}

impl<C: Clone> Clone for DomainSeeds<C> {
    fn clone(&self) -> Self {
        if self.seed_provider.is_some() {
            panic!("DomainSeeds with a seed provider cannot be cloned before initialization");
        }
        Self {
            seeds: self.seeds.clone(),
            seed_provider: None,
        }
    }
}

impl<C: Clone + fmt::Debug> fmt::Debug for DomainSeeds<C> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("DomainSeeds")
            .field("seeds", &self.seeds)
            .field("has_seed_provider", &self.seed_provider.is_some())
            .finish()
    }
}

impl<C: Clone> DomainSeeds<C> {
    pub fn extend_seeds(&mut self, seeds: impl IntoIterator<Item = C>) {
        self.seeds.extend(seeds);
    }

    pub fn set_provider<F>(&mut self, provider: F)
    where
        F: FnOnce() -> Vec<C> + Send + Sync + 'static,
    {
        self.seed_provider = Some(Box::new(provider));
    }

    /// Evaluates lazy seed provider (if present) and returns a random seed with 50% probability.
    pub fn sample(&mut self, rng: &mut dyn rand::Rng) -> Option<C> {
        if let Some(seed_provider) = self.seed_provider.take() {
            self.extend_seeds(seed_provider());
        }
        if self.seeds.is_empty() || !rng.random_bool(0.5) {
            None
        } else {
            let idx = rng.random_range(0..self.seeds.len());
            Some(self.seeds[idx].clone())
        }
    }
}

pub trait SeedableDomain: Domain + Sized {
    /// Mutable accessor to the domain's seed storage.
    fn seeds_mut(&mut self) -> &mut DomainSeeds<Self::CorpusValue>;

    /// Adds pre-defined seeds. Panics if any seed is invalid for this domain.
    fn with_seeds(mut self, seeds: impl IntoIterator<Item = impl Into<Self::CorpusValue>>) -> Self {
        for seed in seeds {
            let corpus_val = seed.into();
            if let Err(e) = self.validate_corpus_value(&corpus_val) {
                panic!("Invalid seed value for domain: {e:?}");
            }
            self.seeds_mut().extend_seeds([corpus_val]);
        }
        self
    }

    /// Non-panicking version for programmatic usage.
    fn try_with_seeds(
        mut self,
        seeds: impl IntoIterator<Item = impl Into<Self::CorpusValue>>,
    ) -> anyhow::Result<Self> {
        for seed in seeds {
            let corpus_val = seed.into();
            self.validate_corpus_value(&corpus_val)?;
            self.seeds_mut().extend_seeds([corpus_val]);
        }
        Ok(self)
    }

    /// Adds a lazy seed provider evaluated on first sampling.
    fn with_seed_provider<F, I, S>(mut self, seed_provider: F) -> Self
    where
        F: FnOnce() -> I + Send + Sync + 'static,
        I: IntoIterator<Item = S>,
        Self::CorpusValue: From<S>,
    {
        self.seeds_mut().set_provider(move || {
            seed_provider().into_iter().map(Self::CorpusValue::from).collect()
        });
        self
    }
}

/// A type-erased interface for Domain types.
///
/// This trait is used to expose a common interface for Domain types to the fuzzing engine through
/// the `FuzzTest` trait.
/// The methods of this trait are similar to that of the `Domain` trait, but they operate on
/// a type-erased `GenericCorpusValue` instead of an explicit type.
pub trait GenericDomain {
    /// Initializes a new value drawn from the domain.
    ///
    /// See `Domain::init` for more details.
    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<GenericCorpusValue>;

    /// Mutates the value in `val` to a new value drawn from the domain.
    ///
    /// See `Domain::mutate` for more details.
    fn mutate(
        &mut self,
        val: &mut GenericCorpusValue,
        rng: &mut dyn rand::Rng,
        only_shrink: bool,
    ) -> anyhow::Result<()>;

    /// Parses a slice of bytes into a `GenericCorpusValue`.
    ///
    /// See `Domain::parse_corpus` for more details.
    fn parse_corpus(&self, data: &[u8]) -> anyhow::Result<GenericCorpusValue>;

    /// Serializes a `GenericCorpusValue` to a Vec of bytes (ie, Vec<u8>).
    ///
    /// See `Domain::serialize_corpus` for more details.
    fn serialize_corpus(&self, val: &GenericCorpusValue) -> anyhow::Result<Vec<u8>>;
}

/// Blanket implementation of the `GenericDomain` trait for types implementing the `Domain` trait.
///
/// This implementation is a simple pass-through implementation that uses the methods of the
/// `Domain` trait to implement the `GenericDomain` trait.
impl<D> GenericDomain for D
where
    D: Domain,
    D::CorpusValue: 'static,
{
    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<GenericCorpusValue> {
        Ok(Box::new(self.init(rng)?))
    }

    /// Retrieves the underlying `Domain`'s `CorpusValue` from the `GenericCorpusValue` and calls
    /// the underlying `Domain::mutate` method.
    ///
    /// If the `GenericCorpusValue` cannot be downcasted to the underlying `Domain`'s `CorpusValue`
    /// then an Error is returned.
    ///
    /// See `GenericDomain::mutate` for more details.
    fn mutate(
        &mut self,
        val: &mut GenericCorpusValue,
        rng: &mut dyn rand::Rng,
        only_shrink: bool,
    ) -> anyhow::Result<()> {
        self.mutate(
            val.downcast_mut().context("Failed to retrieve the Corpus Value")?,
            rng,
            only_shrink,
        )
    }

    /// Calls the underlying `Domain::parse_corpus` method with the `data` and wraps the resulting
    /// `CorpusValue` in a `GenericCorpusValue`.
    ///
    /// See `GenericDomain::parse_corpus` for more details.
    fn parse_corpus(&self, data: &[u8]) -> anyhow::Result<GenericCorpusValue> {
        Ok(Box::new(self.parse_corpus(data)?))
    }

    /// Retrieves the underlying `Domain`'s `CorpusValue` from the `GenericCorpusValue` and calls
    /// the underlying `Domain::serialize_corpus` method.
    ///
    /// If the `GenericCorpusValue` cannot be downcasted to the underlying `Domain`'s `CorpusValue`
    /// then an Error is returned.
    ///
    /// See `GenericDomain::serialize_corpus` for more details.
    fn serialize_corpus(&self, val: &GenericCorpusValue) -> anyhow::Result<Vec<u8>> {
        self.serialize_corpus(val.downcast_ref().context("Failed to retrieve the Corpus Value")?)
    }
}
