use std::sync::Arc;
use super::controller::RaidArray;
use super::{RaidAlgorithm, RaidLevel, RaidError, MemberStatus};

pub struct Raid1 {
    array: Arc<RaidArray>,
}

impl Raid1 {
    pub fn new(array: Arc<RaidArray>) -> Self {
        Raid1 { array }
    }
}

impl RaidAlgorithm for Raid1 {
    fn read(&mut self, block_offset: u64, size: u64) -> Result<Vec<u8>, RaidError> {
        let member = &self.array.members[0];
        
        if member.status != MemberStatus::Online {
            return Err("Member offline".into());
        }
        
        let file = std::fs::File::open(&member.device_path)?;
        use std::io::{Read, Seek};
        let mut file = file;
        file.seek(std::io::SeekFrom::Start(block_offset))?;
        
        let mut buffer = vec![0u8; size as usize];
        file.read_exact(&mut buffer)?;
        
        Ok(buffer)
    }
    
    fn write(&mut self, block_offset: u64, data: &[u8]) -> Result<(), RaidError> {
        for member in &self.array.members {
            if member.status != MemberStatus::Online {
                continue;
            }
            
            let file = std::fs::OpenOptions::new()
                .write(true)
                .open(&member.device_path)?;
            use std::io::{Write, Seek};
            let mut file = file;
            file.seek(std::io::SeekFrom::Start(block_offset))?;
            file.write_all(data)?;
        }
        
        Ok(())
    }
    
    fn get_total_size(&self) -> u64 {
        self.array.total_size
    }
    
    fn get_level(&self) -> RaidLevel {
        RaidLevel::RAID1
    }
}