// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! SequentialIoGenerator generates sequential IO an a file.
//! IOs will be of different size. Every next IO will start where previous one
//! end in a non overlapping way. When generator reaches end of allowed range,
//! the next offset will wrap around and starts from the beginning of the range.
#![deny(warnings)]

use {
    crate::generator::Generator,
    crate::operations::OperationType,
    byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt},
    std::{io::Cursor, mem, ops::Range},
};

enum FillType {
    ZeroFill,
}

/// Rounds up x to next multiple of align and returns the rounded up value.
pub fn round_up(x: usize, align: usize) -> usize {
    if align == 0 {
        x
    } else {
        ((x + align - 1) / align) * align
    }
}

pub struct SequentialIoGenerator {
    // See struct Header
    magic_number: u64,

    // See struct Header
    process_id: u64,

    // See struct Header
    fd_unique_id: u64,

    // See struct Header
    generator_unique_id: u64,

    // Range within which IO should be performed
    offset_range: Range<u64>,

    // This offset points location where next IO should be performed
    current_offset: u64,

    next_start_offset: u64,

    // last "random" number that was generated
    last_number: u64,

    // How to fill the buffer
    _fill_type: FillType,

    // block size suggest where to write headers in the buffer
    block_size: u64,

    max_io_size: u64,

    // If true aligns the ios to block_size
    align: bool,
}

impl SequentialIoGenerator {
    pub fn new(
        magic_number: u64,
        process_id: u64,
        fd_unique_id: u64,
        generator_unique_id: u64,
        offset_range: Range<u64>,
        block_size: u64,
        max_io_size: u64,
        align: bool,
    ) -> SequentialIoGenerator {
        return SequentialIoGenerator {
            magic_number,
            process_id,
            fd_unique_id,
            generator_unique_id,
            offset_range: offset_range.clone(),
            current_offset: offset_range.start,
            last_number: 0,
            _fill_type: FillType::ZeroFill,
            block_size,
            max_io_size,
            align,
            next_start_offset: offset_range.start,
        };
    }

    /// We zero fill all buffers - because it was less programmer-time consuming.
    /// This is unnecessary and cpu time-consuming. TODO(auradkar): Introduce
    /// alternate ways.
    fn zero_fill(&self, buf: &mut Vec<u8>) {
        buf.resize(buf.capacity(), 0);
    }

    /// The function writes block header(s) to the buffer. We write block_header
    /// the beginning of each block. Some buffer may range over multiple blocks.
    /// If so this routine write to each such block start.
    /// Buffers may very in size and offset. Not all buffers may be large enough
    /// to hold the header and not all buffers may overlap with beginning of the
    /// block.
    /// TODO(auradkar): SInce current IOs are always 4KiB aligned, this function
    /// works well. But not all unaligned cases are covered by this function.
    fn write_headers(&self, buf: &mut Vec<u8>, sequence_number: u64, offset_range: Range<u64>) {
        let start = round_up(offset_range.start as usize, self.block_size as usize);
        let end = offset_range.end as usize;
        let header_size = mem::size_of::<Header>();
        let mut offset = start;

        while offset + header_size < end {
            let header = Header::new(
                self.magic_number,
                self.process_id,
                self.fd_unique_id,
                self.generator_unique_id as u64,
                sequence_number,
                offset as u64,
                buf.capacity() as u64,
                self.last_number,
            );

            let buf_offset = offset - start;
            header.write_header(&mut buf[buf_offset..(buf_offset + header_size)]);

            offset += self.block_size as usize;
        }
    }

    fn io_size(&self) -> u64 {
        let max_blocks = self.max_io_size / self.block_size;
        let size = ((self.last_number % max_blocks as u64) + 1) * self.block_size;
        size
    }
}

impl Generator for SequentialIoGenerator {
    fn generate_number(&mut self) -> u64 {
        // NOTE: We don't generate number zero.
        self.last_number += 1;
        self.current_offset = self.next_start_offset;

        if !self.align {
            panic!("unaligned write not implemented yet");
        }

        let size = self.io_size();
        self.next_start_offset += size;
        if self.next_start_offset >= self.offset_range.end {
            self.next_start_offset = self.offset_range.start
        }

        self.last_number
    }

    fn get_io_operation(&self, allowed_ops: &Vec<OperationType>) -> OperationType {
        let index = self.last_number as usize % allowed_ops.len();
        allowed_ops[index]
    }

    fn get_io_range(&self) -> Range<u64> {
        let cur = self.current_offset;

        let size = self.io_size();
        let mut end = cur + size;

        if end >= self.offset_range.end {
            end = self.offset_range.end;
        }

        (cur..end)
    }

    fn fill_buffer(&self, buf: &mut Vec<u8>, sequence_number: u64, offset_range: Range<u64>) {
        self.zero_fill(buf);
        self.write_headers(buf, sequence_number, offset_range);
    }
}

/// Each block of written data contains a header field. This field helps us to
/// verify the written data. In future this also acts as poison value to detect
/// any corruptions. TODO(auradkar): This needs a better home.
#[derive(Default)]
struct Header {
    /// magic_number helps to identify that the block was written
    /// by the app
    magic_number: u64,

    /// process_id helps to differentiate this run from other runs
    process_id: u64,

    /// fd_unique_id tells what file descriptor was used to write
    /// this data
    fd_unique_id: u64,

    /// generator_unique_id is unique id of the generator that
    /// updated this block
    generator_unique_id: u64,

    /// io_op_unique_id tells which io operation updated this block
    io_op_unique_id: u64,

    // file_offset is offset within the file where this data
    // should be found
    file_offset: u64,

    /// size of the IO that wrote this header
    size: u64,

    /// seed that was used to generate the rest of the data in this
    /// block
    seed: u64,

    /// Stores the crc32 of this header
    crc32: u32,
}

impl Header {
    fn new(
        magic_number: u64,
        process_id: u64,
        fd_unique_id: u64,
        generator_unique_id: u64,
        io_op_unique_id: u64,
        file_offset: u64,
        size: u64,
        seed: u64,
    ) -> Header {
        let header = Header {
            magic_number,
            process_id,
            fd_unique_id,
            generator_unique_id,
            io_op_unique_id,
            file_offset,
            size,
            seed,
            crc32: 0,
        };

        // TODO(auradkar): compute crc32 or some equivalent. Couldn't find a
        // crate that does compute 64/32-bit checksum in the repo.
        header
    }

    /// Convert byte vector to header
    #[allow(dead_code)]
    pub fn read_header(buf: &[u8]) -> Header {
        let mut cursor = Cursor::new(buf);
        let mut header: Header = Default::default();

        header.magic_number = cursor.read_u64::<LittleEndian>().unwrap();

        header.process_id = cursor.read_u64::<LittleEndian>().unwrap();

        header.fd_unique_id = cursor.read_u64::<LittleEndian>().unwrap();

        header.generator_unique_id = cursor.read_u64::<LittleEndian>().unwrap();

        header.io_op_unique_id = cursor.read_u64::<LittleEndian>().unwrap();

        header.file_offset = cursor.read_u64::<LittleEndian>().unwrap();

        header.size = cursor.read_u64::<LittleEndian>().unwrap();

        header.seed = cursor.read_u64::<LittleEndian>().unwrap();

        header.crc32 = cursor.read_u32::<LittleEndian>().unwrap();

        header
    }

    /// Copy header into byte vector
    fn write_header(&self, buf: &mut [u8]) {
        let mut cursor = Cursor::new(buf);

        cursor.write_u64::<LittleEndian>(self.magic_number).unwrap();

        cursor.write_u64::<LittleEndian>(self.process_id).unwrap();

        cursor.write_u64::<LittleEndian>(self.fd_unique_id).unwrap();

        cursor.write_u64::<LittleEndian>(self.generator_unique_id).unwrap();

        cursor.write_u64::<LittleEndian>(self.io_op_unique_id).unwrap();

        cursor.write_u64::<LittleEndian>(self.file_offset).unwrap();

        cursor.write_u64::<LittleEndian>(self.size).unwrap();

        cursor.write_u64::<LittleEndian>(self.seed).unwrap();

        cursor.write_u32::<LittleEndian>(self.crc32).unwrap();
    }
}

#[cfg(test)]
mod tests {
    use {
        crate::generator::Generator,
        crate::operations::OperationType,
        crate::sequential_io_generator::{Header, SequentialIoGenerator},
        std::ops::Range,
    };

    static MAGIC_NUMBER: u64 = 100;
    static PROCESS_ID: u64 = 101;
    static TARGET_ID: u64 = 102;
    static GENERATOR_ID: u64 = 103;
    static ALIGN: bool = true;

    fn create_generator(
        block_size: u64,
        target_range: Range<u64>,
        max_io_size: u64,
    ) -> SequentialIoGenerator {
        SequentialIoGenerator::new(
            MAGIC_NUMBER,
            PROCESS_ID,
            TARGET_ID,
            GENERATOR_ID,
            target_range,
            block_size,
            max_io_size,
            ALIGN,
        )
    }

    // Test for one block per io.
    #[test]
    fn simple_test() {
        let block_size = 4096 as u64;
        let target_range = 0..2 * block_size;
        let mut gen = create_generator(block_size, target_range, block_size);

        assert_eq!(gen.generate_number(), 1);
        let operations_vec = vec![OperationType::Write];
        assert_eq!(gen.get_io_operation(&operations_vec), OperationType::Write);
        assert_eq!(gen.get_io_range(), 0..block_size);

        assert_eq!(gen.generate_number(), 2);
        let operations_vec = vec![OperationType::Write];
        assert_eq!(gen.get_io_operation(&operations_vec), OperationType::Write);

        let operations_vec = vec![OperationType::Open, OperationType::Write];
        assert_eq!(gen.get_io_operation(&operations_vec), OperationType::Open);

        let operations_vec = vec![OperationType::Write, OperationType::Open];
        assert_eq!(gen.get_io_operation(&operations_vec), OperationType::Write);
        assert_eq!(gen.get_io_range(), block_size..2 * block_size);

        assert_eq!(gen.generate_number(), 3);
        let operations_vec = vec![OperationType::Write, OperationType::Open];
        assert_eq!(gen.get_io_operation(&operations_vec), OperationType::Open);
        assert_eq!(gen.get_io_range(), 0..block_size);
    }

    // Test for generating multiple blocks.
    #[test]
    fn multi_block_test() {
        let block_size = 4096 as u64;
        let target_range = 0..5 * block_size;
        let mut gen = create_generator(block_size, target_range.clone(), block_size * 4);

        assert_eq!(gen.generate_number(), 1);
        let mut start = 0;
        let mut end = (1 + 1) * block_size;
        assert_eq!(gen.get_io_range(), start..end);

        assert_eq!(gen.generate_number(), 2);
        start = end;
        end = target_range.end;
        assert_eq!(gen.get_io_range(), start..end);

        assert_eq!(gen.generate_number(), 3);
        start = 0;
        end = start + (3 + 1) * block_size;
        assert_eq!(gen.get_io_range(), start..end);

        assert_eq!(gen.generate_number(), 4);
        start = end;
        end = start + block_size;
        assert_eq!(gen.get_io_range(), start..end);
    }

    // Range test - Test if all the generated ios are withing given target range
    #[test]
    fn range_test() {
        let block_size = 4096 as u64;
        let target_range = 20 * block_size..50 * block_size;
        let max_io_size = 10 * block_size;
        let mut gen = create_generator(block_size, target_range.clone(), max_io_size);

        for _i in 0..2000 {
            gen.generate_number();
            let range = gen.get_io_range();
            assert_eq!(range.start >= target_range.start, true);
            assert_eq!((range.start + block_size) <= range.end, true);
            assert_eq!(range.end <= target_range.end, true);
            assert_eq!(range.start < target_range.end, true);
        }
    }

    // Size test - Test if the size of the IO falls withing the specified limit
    #[test]
    fn size_test() {
        let block_size = 4096 as u64;
        let target_range = 20 * block_size..50 * block_size;
        let max_io_size = 10 * block_size;
        let mut gen = create_generator(block_size, target_range, max_io_size);

        for _i in 0..2000 {
            gen.generate_number();
            let range = gen.get_io_range();
            assert_eq!((range.end - range.start) <= max_io_size, true);
            assert_eq!((range.end - range.start) > 0, true);
        }
    }

    // Read/write block header.
    #[test]
    fn header_test() {
        let block_size = 4096 as u64;
        let target_range = 20 * block_size..50 * block_size;
        let max_io_size = 10 * block_size;
        let gen = create_generator(block_size, target_range, max_io_size);

        let mut buf = vec![0 as u8; block_size as usize];
        let io_offset_range = block_size..2 * 4096;
        let io_op_unique_id = 10 as u64;
        gen.fill_buffer(&mut buf, io_op_unique_id, io_offset_range.clone());
        let header: Header = Header::read_header(&buf);
        assert_eq!(header.magic_number, MAGIC_NUMBER);
        assert_eq!(header.process_id, PROCESS_ID);
        assert_eq!(header.fd_unique_id, TARGET_ID);
        assert_eq!(header.generator_unique_id, GENERATOR_ID);
        assert_eq!(header.io_op_unique_id, io_op_unique_id);
        assert_eq!(header.file_offset, io_offset_range.start);
        assert_eq!(header.size, io_offset_range.end - io_offset_range.start);
    }
}
