use rand::RngExt;
use std::fmt;

use super::Domain;

const DEFAULT_MAX_LEN: usize = 5000;

macro_rules! choose_one {
    ($rng:expr, $( $cond:expr $(; w = $weight:expr)? => $action:expr ),* $(,)? ) => {{
        struct Branch {
            cond: bool,
            weight: usize,
        }

        let branches = [
            $( Branch { cond: $cond, weight: choose_one!(@default 1usize, $($weight)?) } ),*
        ];
        let total_weight: usize = branches.iter()
            .map(|&Branch { cond, weight }| if cond { weight } else { 0 })
            .sum();

        if total_weight > 0 {
            let choice = ::rand::RngExt::random_range($rng, 0..total_weight);
            let mut current = 0usize;
            let mut i = 0usize;
            'choose_one_loop: {
                $(
                    if branches[i].cond {
                        let w = branches[i].weight;
                        if choice >= current && choice < current + w {
                            let _ = { $action };
                            break 'choose_one_loop;
                        }
                        #[allow(unused_assignments)]
                        { current += w; }
                    }
                    i += 1;
                )*
            }
        }
    }};
    (@default $default:expr, ) => { $default };
    (@default $default:expr, $val:expr) => { $val };
}

/// A trait for configuring the length constraints of container domains.
///
/// This trait provides a fluent interface to specify the length requirements
/// for domains that generate collections, such as [`VecOf`].
pub trait ContainerDomain: Sized {
    /// Sets the length of the container to be exactly `len`.
    fn with_len(self, len: usize) -> Self;

    /// Sets the minimum length of the container.
    ///
    /// # Panics
    ///
    /// Panics if the specified `min_len` is greater than the current maximum length (if set).
    fn with_min_len(self, min_len: usize) -> Self;

    /// Sets the maximum length of the container.
    ///
    /// Using this API will override any previous `with_soft_max_len` call.
    ///
    /// # Panics
    ///
    /// Panics if the specified `max_len` is less than the current minimum length.
    fn with_max_len(self, max_len: usize) -> Self;

    /// Sets a "soft" maximum length of the container.
    ///
    /// Using this API will override any previous `with_max_len` call.
    ///
    /// With this constraint, the domain will consider containers longer than
    /// `soft_max_len` as valid. When mutating the containers, the domain will
    /// not increase their size further if it is already greater or equal to
    /// `soft_max_len`.
    ///
    /// # Panics
    ///
    /// Panics if the specified `soft_max_len` is less than the current minimum length.
    fn with_soft_max_len(self, soft_max_len: usize) -> Self;
}

pub struct VecOf<T> {
    inner: T,
    min_len: usize,
    max_len: Option<usize>,
    max_len_is_soft: bool,
}

impl<T: Clone> Clone for VecOf<T> {
    fn clone(&self) -> Self {
        Self {
            inner: self.inner.clone(),
            min_len: self.min_len,
            max_len: self.max_len,
            max_len_is_soft: self.max_len_is_soft,
        }
    }
}

impl<T: fmt::Debug> fmt::Debug for VecOf<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("VecOf")
            .field("inner", &self.inner)
            .field("min_len", &self.min_len)
            .field("max_len", &self.max_len)
            .field("max_len_is_soft", &self.max_len_is_soft)
            .finish()
    }
}

impl<T> VecOf<T> {
    pub fn new(inner: T) -> Self {
        Self { inner, min_len: 0, max_len: None, max_len_is_soft: false }
    }

    fn max_len(&self) -> usize {
        self.max_len.unwrap_or(self.min_len.max(DEFAULT_MAX_LEN))
    }
}

impl<T> Domain for VecOf<T>
where
    T: Domain,
{
    type CorpusValue = Vec<T::CorpusValue>;
    type UserValue<'user> = Vec<T::UserValue<'user>>;

    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
        if self.max_len() == 0 {
            return Ok(Vec::new());
        }

        let initial_size = if self.min_len == 0 { rng.random_range(0..=1) } else { self.min_len };

        let mut val = Vec::with_capacity(initial_size);
        for _ in 0..initial_size {
            val.push(self.inner.init(rng)?);
        }
        Ok(val)
    }

    fn mutate(
        &self,
        val: &mut Self::CorpusValue,
        rng: &mut dyn rand::Rng,
        only_shrink: bool,
    ) -> anyhow::Result<()> {
        if self.max_len_is_soft {
            anyhow::ensure!(
                self.min_len <= val.len(),
                "Length {} is less than the minimum length {}",
                val.len(),
                self.min_len
            );
        } else {
            anyhow::ensure!(
                self.min_len <= val.len() && val.len() <= self.max_len(),
                "Length {} is not between the minimum length {} and maximum length {}",
                val.len(),
                self.min_len,
                self.max_len()
            );
        }

        choose_one!(rng,
            val.len() > self.min_len => {
                let idx = rng.random_range(0..val.len());
                val.remove(idx);
            },
            !only_shrink && val.len() < self.max_len() => {
                let idx = rng.random_range(0..=val.len());
                val.insert(idx, self.inner.init(rng)?);
            },
            !val.is_empty() => {
                let idx = rng.random_range(0..val.len());
                self.inner.mutate(&mut val[idx], rng, only_shrink)?;
            },
        );

        Ok(())
    }

    fn get_user_value<'a>(
        &self,
        corpus_value: &'a Self::CorpusValue,
    ) -> anyhow::Result<Self::UserValue<'a>> {
        let mut user_values = Vec::with_capacity(corpus_value.len());
        for item in corpus_value {
            user_values.push(self.inner.get_user_value(item)?);
        }
        Ok(user_values)
    }
}

impl<T> ContainerDomain for VecOf<T> {
    fn with_len(self, len: usize) -> Self {
        Self { min_len: len, max_len: Some(len), ..self }
    }

    fn with_min_len(self, min_len: usize) -> Self {
        assert!(
            self.max_len.is_none_or(|max| min_len <= max),
            "Minimum length {} cannot be greater than the maximum length {}",
            min_len,
            self.max_len.unwrap()
        );
        Self { min_len, ..self }
    }

    fn with_max_len(self, max_len: usize) -> Self {
        assert!(
            max_len >= self.min_len,
            "Maximum length {} cannot be less than the minimum length {}",
            max_len,
            self.min_len
        );
        Self { max_len_is_soft: false, max_len: Some(max_len), ..self }
    }

    fn with_soft_max_len(self, soft_max_len: usize) -> Self {
        assert!(
            soft_max_len >= self.min_len,
            "Soft maximum length {} cannot be less than the minimum length {}",
            soft_max_len,
            self.min_len
        );
        Self { max_len_is_soft: true, max_len: Some(soft_max_len), ..self }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::domains::arbitrary::Arbitrary;
    use googletest::prelude::*;
    use rand::rngs::{SmallRng, SysRng};
    use rand::SeedableRng;

    fn get_rng() -> SmallRng {
        SmallRng::try_from_rng(&mut SysRng).expect("Failed to create RNG")
    }

    #[gtest]
    fn test_vec_of_mutate_shrink() {
        let domain = VecOf::new(Arbitrary::<u32>::default()).with_max_len(10);

        let mut rng = get_rng();

        let mut val = vec![1, 2, 3, 4, 5];

        // Test shrinking length
        for _ in 0..100 {
            let orig_len = val.len();
            if orig_len == 0 {
                break;
            }
            domain.mutate(&mut val, &mut rng, true).unwrap();
            expect_that!(val.len(), le(orig_len));
        }
    }

    #[gtest]
    fn test_vec_of_mutate_grow_and_change() {
        let domain = VecOf::new(Arbitrary::<u32>::default()).with_max_len(10);

        let mut rng = get_rng();

        let mut val = vec![1];
        let mut grew = false;

        for _ in 0..100 {
            let orig_len = val.len();
            domain.mutate(&mut val, &mut rng, false).unwrap();
            expect_that!(val.len(), le(10));
            if val.len() > orig_len {
                grew = true;
            }
        }
        expect_that!(grew, eq(true), "VecOf should be able to grow during normal mutation");
    }

    #[gtest]
    fn test_vec_of_init_respects_min_len() {
        let domain = VecOf::new(Arbitrary::<u32>::default()).with_min_len(5);
        let mut rng = get_rng();

        for _ in 0..100 {
            let val = domain.init(&mut rng).unwrap();
            expect_that!(val.len(), ge(5));
        }
    }

    #[gtest]
    fn test_vec_of_init_fixed_len() {
        let domain = VecOf::new(Arbitrary::<u32>::default()).with_len(7);
        let mut rng = get_rng();

        for _ in 0..100 {
            let val = domain.init(&mut rng).unwrap();
            expect_that!(val.len(), eq(7));
        }
    }

    #[gtest]
    fn test_vec_of_init_default_max_len() {
        let domain = VecOf::new(Arbitrary::<u32>::default());
        let mut rng = get_rng();

        for _ in 0..100 {
            let val = domain.init(&mut rng).unwrap();
            expect_that!(val.len(), le(DEFAULT_MAX_LEN));
        }
    }

    #[gtest]
    fn test_vec_of_mutate_respects_min_len() {
        let domain = VecOf::new(Arbitrary::<u32>::default()).with_min_len(3);
        let mut rng = get_rng();

        let mut val = vec![1, 2, 3];
        for _ in 0..100 {
            domain.mutate(&mut val, &mut rng, true).unwrap();
            expect_that!(val.len(), ge(3));
        }
    }

    #[gtest]
    fn test_vec_of_mutate_respects_max_len() {
        let domain = VecOf::new(Arbitrary::<u32>::default()).with_max_len(3);
        let mut rng = get_rng();

        let mut val = vec![1, 2, 3];
        for _ in 0..100 {
            domain.mutate(&mut val, &mut rng, false).unwrap();
            expect_that!(val.len(), le(3));
        }
    }

    #[gtest]
    fn test_vec_of_mutate_min_len_validation() {
        let domain = VecOf::new(Arbitrary::<u32>::default()).with_min_len(5);
        let mut rng = get_rng();

        let mut val = vec![1, 2, 3]; // Length 3, which is < 5
        let result = domain.mutate(&mut val, &mut rng, false);
        expect_that!(result.is_err(), eq(true));
        let err_msg = format!("{}", result.unwrap_err());
        expect_that!(
            err_msg,
            contains_substring(
                "Length 3 is not between the minimum length 5 and maximum length 5000"
            )
        );
    }

    #[gtest]
    fn test_vec_of_mutate_soft_max_len_behavior() {
        let domain = VecOf::new(Arbitrary::<u32>::default()).with_soft_max_len(5);
        let mut rng = get_rng();

        // Valid mutation within bounds
        let mut valid_val = vec![1, 2, 3, 4, 5];
        let valid_result = domain.mutate(&mut valid_val, &mut rng, false);
        expect_that!(valid_result.is_ok(), eq(true));

        // In soft max mode, we DON'T error if we are already over the limit on entry
        let mut over_val = vec![1, 2, 3, 4, 5, 6];
        let result = domain.mutate(&mut over_val, &mut rng, false);
        expect_that!(result.is_ok(), eq(true));
        // But it should not have grown further
        expect_that!(over_val.len(), le(6));
    }

    #[gtest]
    #[should_panic(expected = "Minimum length 6 cannot be greater than the maximum length 5")]
    fn test_vec_of_with_invalid_min_len() {
        VecOf::new(Arbitrary::<u32>::default()).with_max_len(5).with_min_len(6);
    }

    #[gtest]
    #[should_panic(expected = "Maximum length 4 cannot be less than the minimum length 5")]
    fn test_vec_of_with_invalid_max_len() {
        VecOf::new(Arbitrary::<u32>::default()).with_min_len(5).with_max_len(4);
    }

    #[gtest]
    #[should_panic(expected = "Soft maximum length 4 cannot be less than the minimum length 5")]
    fn test_vec_of_with_invalid_soft_max_len() {
        VecOf::new(Arbitrary::<u32>::default()).with_min_len(5).with_soft_max_len(4);
    }

    #[gtest]
    fn test_vec_of_mutate_no_action_at_bounds() {
        let domain = VecOf::new(Arbitrary::<u32>::default()).with_len(1);
        let mut rng = get_rng();

        let mut val = vec![100u32];
        for _ in 0..100 {
            // with_len(1) means min=1, max=1.
            // insert/remove should be disabled.
            // mutate inner should still be possible.
            let orig_val = val[0];
            domain.mutate(&mut val, &mut rng, false).unwrap();
            expect_that!(val.len(), eq(1));
            // In this case, since action_count will be 1 (can_change), it MUST call inner.mutate
            // Arbitrary::<u32> mutate should eventually change the value.
            if val[0] != orig_val {
                return;
            }
        }
    }

    #[gtest]
    fn test_vec_of_zero_len() {
        let domain = VecOf::new(Arbitrary::<u32>::default()).with_len(0);
        let mut rng = get_rng();

        let val = domain.init(&mut rng).unwrap();
        expect_that!(val, is_empty());

        let mut val = Vec::new();
        domain.mutate(&mut val, &mut rng, false).unwrap();
        expect_that!(val, is_empty());
    }

    #[gtest]
    fn test_vec_of_get_user_value() {
        let domain = VecOf::new(Arbitrary::<u32>::default());
        let corpus_val = vec![1u32, 2u32, 3u32];
        let user_val = domain.get_user_value(&corpus_val).unwrap();
        expect_that!(user_val, container_eq(vec![1u32, 2u32, 3u32]));
    }
}
