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

use super::Domain;

use anyhow;
use rand::distr::uniform::SampleUniform;
use rand::distr::uniform::UniformSampler;

/// Generates values of type `T` in a given range.
///
/// For example, `InRange::new(0, 100)` generates integer
/// values from the inclusive range `[0, 100]`.
///
/// Example usage:
/// ```
/// # use fuzztest::domains::Domain;
/// # use fuzztest::domains::range::InRange;
/// # use rand::prelude::*;
///
/// let mut range_i32 = InRange::new(21i32, 73);
/// let sample = range_i32.init(&mut rand::rng());
///
/// assert!(sample.is_ok());
/// let sample = sample.unwrap();
/// assert!(sample >= 21);
/// assert!(sample <= 73);
/// ```
pub struct InRange<T> {
    lower: T,
    upper: T,
}

impl InRange<i32> {
    pub fn new(lower: i32, upper: i32) -> Self {
        Self { lower, upper }
    }

    pub fn get_in_range(&self, rng: &mut dyn rand::Rng) -> i32 {
        <i32 as SampleUniform>::Sampler::sample_single(self.lower, self.upper, rng)
            .expect("Failed to sample from Uniform distribution")
    }
}

impl Domain for InRange<i32> {
    type UserValue<'user> = i32;
    type CorpusValue = i32;

    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
        Ok(self.get_in_range(rng))
    }

    fn mutate(
        &mut self,
        val: &mut Self::CorpusValue,
        rng: &mut dyn rand::Rng,
        only_shrink: bool,
    ) -> anyhow::Result<()> {
        if only_shrink {
            *val -= 1;
        } else {
            *val = self.get_in_range(rng);
        }
        Ok(())
    }

    fn corpus_to_user_value<'a>(
        &self,
        corpus_value: &'a Self::CorpusValue,
    ) -> anyhow::Result<Self::UserValue<'a>> {
        Ok(*corpus_value)
    }

    fn validate_corpus_value(&self, corpus_value: &Self::CorpusValue) -> anyhow::Result<()> {
        if *corpus_value < self.lower || *corpus_value > self.upper {
            anyhow::bail!(
                "Value {} is out of range [{}, {}]",
                corpus_value,
                self.lower,
                self.upper
            );
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use rand::SeedableRng;

    use super::*;

    #[test]
    fn test_in_range() {
        let in_range = InRange::<i32>::new(0, 100);
        let mut rng = rand::rngs::StdRng::from_seed([73; 32]);
        let in_range_val = in_range.get_in_range(&mut rng);
        assert!(in_range_val >= 0 && in_range_val <= 100);
    }
}
