#[cfg(test)]
use no_std_io::Writer;

use super::spawn::Spawn;
use no_std_io::{EndianRead, EndianWrite, Reader};

#[derive(Debug, Clone, Copy, EndianWrite, EndianRead)]
pub struct SpawnPair {
    data: [u8; Self::DATA_SIZE],
}

impl SpawnPair {
    pub const DATA_SIZE: usize = 0x80;

    pub fn get_spawner_0(&self) -> Spawn {
        self.default_read_le(0)
    }

    pub fn get_spawner_1(&self) -> Spawn {
        self.default_read_le(Spawn::DATA_SIZE)
    }

    pub fn get_is_active(&self) -> bool {
        // Spawner pairs check index 1 for active
        self.get_spawner_1().get_is_active()
    }

    #[cfg(test)]
    pub fn set_spawner_1(&mut self, spawn: &Spawn) {
        // During tests we'll panic if data isn't set up correctly
        self.write_le(Spawn::DATA_SIZE, spawn).unwrap();
    }
}

impl Default for SpawnPair {
    fn default() -> Self {
        Self {
            data: [0; Self::DATA_SIZE],
        }
    }
}

impl Reader for SpawnPair {
    fn get_slice(&self) -> &[u8] {
        &self.data
    }
}

#[cfg(test)]
impl Writer for SpawnPair {
    fn get_mut_slice(&mut self) -> &mut [u8] {
        &mut self.data
    }
}

#[cfg(test)]
mod test {
    use super::*;

    const ACTIVE_SPAWN_PAIR: SpawnPair = SpawnPair {
        data: [
            0x9d, 0x54, 0x0f, 0x44, 0x15, 0xae, 0xf7, 0x41, 0x08, 0xd0, 0x21, 0x44, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2c, 0xbe, 0x00, 0x00, 0x00, 0x00,
            0x8b, 0x5c, 0x7c, 0x3f, 0x3e, 0x46, 0xf2, 0xdb, 0x91, 0x7d, 0xbe, 0x5c, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x98, 0x3f, 0x42,
            0x15, 0x79, 0x47, 0x42, 0x93, 0x37, 0x40, 0x42, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
            0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0xa7, 0x57, 0xdb, 0xe0, 0x86, 0xe9, 0x9f, 0xb2, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00,
        ],
    };

    const INACTIVE_SPAWN_PAIR: SpawnPair = SpawnPair {
        data: [
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
            0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00,
        ],
    };

    #[test]
    fn should_read_seeds_from_spanwers() {
        assert_eq!(
            ACTIVE_SPAWN_PAIR.get_spawner_0().get_seed(),
            0x5cbe7d91dbf2463e
        );
        assert_eq!(
            ACTIVE_SPAWN_PAIR.get_spawner_1().get_seed(),
            0xb29fe986e0db57a7
        );
    }

    mod get_is_active {
        use super::*;

        #[test]
        fn should_read_active() {
            assert_eq!(ACTIVE_SPAWN_PAIR.get_is_active(), true)
        }

        #[test]
        fn should_read_inactive() {
            assert_eq!(INACTIVE_SPAWN_PAIR.get_is_active(), false)
        }
    }
}
