use crate::bit_vector::*;
use crate::block_device::*;
use crate::errors::*;
use crate::utils::*;

pub struct TestDevice<'a> {
    pub geom: BlockDeviceGeometry,
    pub flash_base: *mut u8,
    pub dirty: BitVector<'a>,
}

impl<'a> TestDevice<'a> {
    pub fn new(geom: BlockDeviceGeometry, flash_base: *mut u8, dirty_bits: &'a mut [u32]) -> Self {
        assert_eq!(geom.block_size * geom.block_count, dirty_bits.len() * 32);
        let result = TestDevice {
            geom: geom,
            flash_base: flash_base,
            dirty: BitVector::new(dirty_bits),
        };
        return result;
    }

    pub fn dirty_count(&self, addr: usize, size: usize) -> Result<usize, BFSErr> {
        let mut result: usize = 0;
        for i in addr..addr + size {
            result += self.dirty.get_bit(i)? as usize;
        }
        return Ok(result);
    }

    pub fn mark_dirty(&mut self, addr: usize, size: usize) -> Result<(), BFSErr> {
        self.dirty.set_range(addr, addr + size)?;
        return Ok(());
    }

    pub fn mark_clean(&mut self, addr: usize, size: usize) -> Result<(), BFSErr> {
        self.dirty.clear_range(addr, addr + size)?;
        return Ok(());
    }
}

/// Preconditions for TestDevice.
/// FIXME - I loosened these up because they were annoying, not sure how strict
/// we should be...

impl<'a> TestDevice<'a> {
    pub fn check_dirty(&self, addr: usize, size: usize) -> Result<(), BFSErr> {
        for i in addr..addr + size {
            dcheck!(self.dirty.get_bit(i)? == 1, BFSErr::CleanRead);
        }
        return Ok(());
    }

    pub fn check_clean(&self, addr: usize, size: usize) -> Result<(), BFSErr> {
        for i in addr..addr + size {
            dcheck!(self.dirty.get_bit(i)? == 0, BFSErr::DirtyWrite);
        }
        return Ok(());
    }

    pub fn check_is_block_sized(&self, data: &[u8]) -> Result<(), BFSErr> {
        dcheck!(data.len() == self.geom.block_size, BFSErr::OutOfBounds);
        return Ok(());
    }

    pub fn check_block_index(&self, iblock: usize) -> Result<(), BFSErr> {
        dcheck!(iblock < self.geom.block_count, BFSErr::OutOfBounds);
        return Ok(());
    }

    pub fn check_fits_in_block(&self, addr: usize, data: &[u8]) -> Result<(), BFSErr> {
        let block_a = addr / self.geom.block_size;
        let block_b = (addr + data.len() - 1) / self.geom.block_size;
        dcheck!(block_a == block_b, BFSErr::OutOfBounds);
        return Ok(());
    }

    pub fn check_read_block(&self, iblock: usize, block: &[u8]) -> Result<(), BFSErr> {
        self.check_block_index(iblock)?;
        self.check_fits_in_block(iblock * self.geom.block_size, block)?;
        //self.check_dirty(iblock * self.geom.block_size, block.len())?;
        return Ok(());
    }

    pub fn check_write_block(&self, iblock: usize, block: &[u8]) -> Result<(), BFSErr> {
        self.check_block_index(iblock)?;
        self.check_fits_in_block(iblock * self.geom.block_size, block)?;
        self.check_clean(iblock * self.geom.block_size, block.len())?;
        return Ok(());
    }

    pub fn check_erase_block(&self, iblock: usize) -> Result<(), BFSErr> {
        self.check_block_index(iblock)?;
        return Ok(());
    }

    pub fn check_erase_dirty_block(&self, iblock: usize) -> Result<(), BFSErr> {
        self.check_erase_block(iblock)?;
        let dirty_count = self.dirty_count(iblock * self.geom.block_size, self.geom.block_size)?;
        dcheck!(dirty_count > 0, BFSErr::BadErase);
        return Ok(());
    }

    pub fn check_range(&self, addr: usize, size: usize) -> Result<(), BFSErr> {
        let bs = self.geom.block_size;
        let bc = self.geom.block_count;
        dcheck!(addr + size < (bc * bs), BFSErr::OutOfBounds);
        return Ok(());
    }

    pub fn check_read_range(&self, addr: usize, data: &mut [u8]) -> Result<(), BFSErr> {
        self.check_range(addr, data.len())?;
        //self.check_dirty(addr, data.len())?;
        return Ok(());
    }

    pub fn check_write_range(&self, addr: usize, data: &[u8]) -> Result<(), BFSErr> {
        self.check_range(addr, data.len())?;
        self.check_clean(addr, data.len())?;
        return Ok(());
    }

    /// Check that this overwrite only changes bits from 1->0
    pub fn check_overwrite_range(&self, addr: usize, data: &[u8]) -> Result<(), BFSErr> {
        self.check_range(addr, data.len())?;
        for i in 0..data.len() {
            let src = data[i];
            unsafe {
                let dst = self.flash_base.add(addr + i).read();
                dcheck!((src & !dst) == 0, BFSErr::BadOverwrite);
            }
        }
        return Ok(());
    }
}

impl<'a> BlockDevice for TestDevice<'a> {
    fn geom(&self) -> BlockDeviceGeometry {
        self.geom
    }

    /// Read a chunk of flash contained in a single block.
    fn read_block(&self, iblock: usize, block: &mut [u8]) -> Result<(), BFSErr> {
        self.check_read_block(iblock, block)?;

        let bs = self.geom.block_size;
        unsafe {
            self.flash_base
                .add(iblock * bs)
                .copy_to(block.as_mut_ptr(), block.len());
        }

        return Ok(());
    }

    /// Write a a chunk of flash contained in a single block.
    fn write_block(&mut self, iblock: usize, block: &[u8]) -> Result<(), BFSErr> {
        self.check_write_block(iblock, block)?;

        let bs = self.geom.block_size;
        unsafe {
            self.flash_base
                .add(iblock * bs)
                .copy_from(block.as_ptr(), bs);
        }

        self.mark_dirty(iblock * bs, bs)?;
        return Ok(());
    }

    /// Erase an entire block of flash.
    fn erase_block(&mut self, iblock: usize) -> Result<(), BFSErr> {
        self.check_erase_block(iblock)?;

        let bs = self.geom.block_size;
        self.mark_clean(iblock * bs, bs)?;
        unsafe {
            self.flash_base.add(iblock * bs).write_bytes(0xFF, bs);
        }

        return Ok(());
    }

    /// Read a range of bytes in flash, checking first that those bytes have
    /// been written since they were erased.
    fn read_range(&self, addr: usize, data: &mut [u8]) -> Result<(), BFSErr> {
        self.check_read_range(addr, data)?;

        unsafe {
            self.flash_base
                .add(addr)
                .copy_to(data.as_mut_ptr(), data.len());
        }

        return Ok(());
    }

    /// Write to a range of bytes in flash, checking first that those bytes have
    /// not been written since they were erased.
    fn write_range(&mut self, addr: usize, data: &[u8]) -> Result<(), BFSErr> {
        self.check_write_range(addr, data)?;

        unsafe {
            self.flash_base
                .add(addr)
                .copy_from(data.as_ptr(), data.len());
        }

        self.mark_dirty(addr, data.len())?;
        return Ok(());
    }

    /// Write to a range of bytes in flash, but _do_ allow writing over dirty
    /// bytes - the result in flash will be the logical AND of the old and new
    /// data.
    fn overwrite_range(&mut self, addr: usize, data: &[u8]) -> Result<(), BFSErr> {
        self.check_overwrite_range(addr, data)?;

        unsafe {
            for i in 0..data.len() {
                let ptr = self.flash_base.add(addr + i);
                ptr.write(ptr.read() & data[i]);
            }
        }

        self.mark_dirty(addr, data.len())?;
        return Ok(());
    }
}

/// Overwriting existing data should write the logical AND of the old and new
/// data.

#[test]
fn test_overwrite() {
    const BLOCK_SIZE: usize = 16;
    const BLOCK_COUNT: usize = 4;
    let geom = BlockDeviceGeometry {
        block_size: BLOCK_SIZE,
        block_count: BLOCK_COUNT,
    };
    let mut buf: [u8; BLOCK_SIZE * BLOCK_COUNT] = [0; BLOCK_SIZE * BLOCK_COUNT];
    let mut dirty_bits = [0; BLOCK_SIZE * BLOCK_COUNT / 32];
    let bd: &mut dyn BlockDevice = &mut TestDevice::new(geom, buf.as_mut_ptr(), &mut dirty_bits);

    let write1: u32 = 0xFF0FF0FF;
    let write2: u32 = 0x0F00F000;

    assert_ok!(bd.write_range(0, &write1.to_le_bytes()));
    assert_ok!(bd.overwrite_range(0, &write2.to_le_bytes()));

    let mut result: u32 = 0;
    assert_ok!(bd.read_range(0, as_unsafe_blob_mut(&mut result)));
    assert_eq!(result, 0xFF0FF0FF & 0x0FF0FF00);
}

/// Trying to set bits that have already been cleared by a previous write should
/// cause a panic in the test device.

#[test]
#[should_panic]
fn test_bad_overwrite() {
    const BLOCK_SIZE: usize = 16;
    const BLOCK_COUNT: usize = 4;
    let geom = BlockDeviceGeometry {
        block_size: BLOCK_SIZE,
        block_count: BLOCK_COUNT,
    };
    let mut buf: [u8; BLOCK_SIZE * BLOCK_COUNT] = [0; BLOCK_SIZE * BLOCK_COUNT];
    let mut dirty_bits = [0; BLOCK_SIZE * BLOCK_COUNT / 32];
    let bd: &mut dyn BlockDevice = &mut TestDevice::new(geom, buf.as_mut_ptr(), &mut dirty_bits);

    let all_1: u32 = 0xFFFFFFFF;
    let all_0: u32 = 0x00000000;

    assert_ok!(bd.write_range(0, &all_0.to_le_bytes()));
    assert_err!(bd.overwrite_range(0, &all_1.to_le_bytes()));
}

/// Trying to read blocks that have never been written should cause a panic in
/// the test device.

#[test]
#[should_panic]
fn test_read_unwritten_block() {
    const BLOCK_SIZE: usize = 16;
    const BLOCK_COUNT: usize = 4;
    let geom = BlockDeviceGeometry {
        block_size: BLOCK_SIZE,
        block_count: BLOCK_COUNT,
    };
    let mut buf: [u8; BLOCK_SIZE * BLOCK_COUNT] = [0; BLOCK_SIZE * BLOCK_COUNT];
    let mut dirty_bits = [0; BLOCK_SIZE * BLOCK_COUNT / 32];
    let bd: &mut dyn BlockDevice = &mut TestDevice::new(geom, buf.as_mut_ptr(), &mut dirty_bits);

    let mut dst_block = [0; BLOCK_SIZE];
    assert_err!(bd.read_block(0, &mut dst_block));
}

/// Trying to read blocks that have been written and then erased should cause a
/// panic in the test device.

#[test]
#[should_panic]
fn test_read_erased_block() {
    const BLOCK_SIZE: usize = 16;
    const BLOCK_COUNT: usize = 4;
    let geom = BlockDeviceGeometry {
        block_size: BLOCK_SIZE,
        block_count: BLOCK_COUNT,
    };
    let mut buf: [u8; BLOCK_SIZE * BLOCK_COUNT] = [0; BLOCK_SIZE * BLOCK_COUNT];
    let mut dirty_bits = [0; BLOCK_SIZE * BLOCK_COUNT / 32];
    let bd: &mut dyn BlockDevice = &mut TestDevice::new(geom, buf.as_mut_ptr(), &mut dirty_bits);

    let mut src_block = [0; BLOCK_SIZE];
    let mut dst_block = [0; BLOCK_SIZE];

    for i in 0..geom.block_size {
        src_block[i] = i as u8;
    }

    assert_ok!(bd.write_block(0, &mut src_block));
    assert_ok!(bd.erase_block(0));
    assert_err!(bd.read_block(0, &mut dst_block));
}

/// All blocks in a device should be readable and writable.

#[test]
fn test_read_write() {
    const BLOCK_SIZE: usize = 16;
    const BLOCK_COUNT: usize = 4;
    let geom = BlockDeviceGeometry {
        block_size: BLOCK_SIZE,
        block_count: BLOCK_COUNT,
    };
    let mut buf: [u8; BLOCK_SIZE * BLOCK_COUNT] = [0; BLOCK_SIZE * BLOCK_COUNT];
    let mut dirty_bits = [0; BLOCK_SIZE * BLOCK_COUNT / 32];
    let bd: &mut dyn BlockDevice = &mut TestDevice::new(geom, buf.as_mut_ptr(), &mut dirty_bits);

    let mut src_block = [0; BLOCK_SIZE];
    let mut dst_block = [0; BLOCK_SIZE];

    for i in 0..geom.block_size {
        src_block[i] = i as u8;
    }

    // Writing clean blocks should succeed.
    for i in 0..geom.block_count {
        assert_ok!(bd.write_block(i, &src_block));
    }

    // Reading those blocks back should succeed, and the contents should match
    // the original block.
    for i in 0..geom.block_count {
        assert_ok!(bd.read_block(i, &mut dst_block));
        for j in 0..geom.block_size {
            assert_eq!(src_block[j], dst_block[j]);
        }
    }

    // Erasing blocks should succeed.
    for i in 0..geom.block_count {
        assert_ok!(bd.erase_block(i));
    }
}
