// 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.

//! File implements IoPacket and Target for POSIX File like objects. Current
//! implementation limits itself to blocking calls.

use {
    crate::common_operations::pwrite,
    crate::io_packet::{IoPacket, IoPacketType, TimeInterval},
    crate::operations::{OperationType, PipelineStages},
    crate::target::{Error, Target, TargetOps, TargetType},
    log::debug,
    log::error,
    std::{
        fs::{File, OpenOptions},
        ops::Range,
        os::unix::io::AsRawFd,
        process,
        result::Result,
        sync::Arc,
        time::Instant,
    },
};

#[derive(Clone)]
pub struct FileIoPacket {
    // io_sequence_number is monotonically increasing number which doesn't
    // repeat for this run and for this generator. This is used to
    // order-replay load.
    io_sequence_number: u64,

    // This value represents the seed used to generate the contents of the
    // IoPacket.
    seed: u64,

    // Start and finish timestamps for different stages of IO.
    stage_timestamps: [TimeInterval; PipelineStages::stage_count()],

    // Type of IO operation
    operation_type: OperationType,

    // Range within the file on which this IO will be performed on. May not
    // applicable to all operations ex. create
    offset_range: Range<u64>,

    // Result of the completed IO operation
    io_result: Option<Error>,

    // The target(file) on which IO will be performed
    target: TargetType,

    // Payload of the IO
    buffer: Vec<u8>,
}

impl FileIoPacket {
    pub fn new(
        operation_type: OperationType,
        io_sequence_number: u64,
        seed: u64,
        offset_range: Range<u64>,
        target: TargetType,
    ) -> FileIoPacket {
        let buffer = vec![0; offset_range.end as usize - offset_range.start as usize];
        FileIoPacket {
            operation_type,
            io_sequence_number,
            seed,
            stage_timestamps: [TimeInterval::new(); PipelineStages::stage_count()],
            offset_range: offset_range.clone(),
            io_result: None,
            target,
            buffer,
        }
    }
}

impl IoPacket for FileIoPacket {
    fn operation_type(&self) -> OperationType {
        self.operation_type
    }

    fn timestamp_stage_start(&mut self, stage: PipelineStages) {
        self.stage_timestamps[stage.stage_number()].start();
    }

    fn timestamp_stage_end(&mut self, stage: PipelineStages) {
        self.stage_timestamps[stage.stage_number()].end();
    }

    fn sequence_number(&self) -> u64 {
        self.io_sequence_number
    }

    fn stage_timestamps(&self) -> &[TimeInterval; PipelineStages::stage_count()] {
        &self.stage_timestamps
    }

    fn interval_to_u64(&self, stage: PipelineStages) -> (u64, u64) {
        self.stage_timestamps[stage.stage_number()].interval_to_u64(&self.target.start_instant())
    }

    fn io_offset_range(&self) -> Range<u64> {
        self.offset_range.clone()
    }

    fn do_io(&mut self) {
        self.target.clone().do_io(self)
    }

    fn is_complete(&self) -> bool {
        self.target.clone().is_complete(self)
    }

    fn verify_needs_io(&self) -> bool {
        self.target.clone().verify_needs_io(self)
    }

    fn generate_verify_io(&mut self) {
        self.target.clone().generate_verify_io(self)
    }

    fn verify(&mut self, verify_packet: &dyn IoPacket) -> bool {
        self.target.clone().verify(self, verify_packet)
    }

    fn get_error(&self) -> Result<(), Error> {
        match &self.io_result {
            Some(error) => Err(error.clone()),
            None => Ok(()),
        }
    }

    fn set_error(&mut self, io_error: Error) {
        self.io_result = Some(io_error);
    }

    fn buffer_mut(&mut self) -> &mut Vec<u8> {
        &mut self.buffer
    }

    fn buffer(&mut self) -> &Vec<u8> {
        &self.buffer
    }
}

pub struct FileBlockingTarget {
    /// File name
    #[allow(unused)]
    name: String,

    /// Open file descriptor
    file: File,

    /// Unique file id for this run and for this generator
    target_unique_id: u64,

    /// Range within which this Targets operates on the file
    offset_range: Range<u64>,

    start_instant: Instant,
}

impl FileBlockingTarget {
    // Create a new Target instance. Fails when opening an existing file fails.
    // TODO(auradkar): Open should be moved to setup phase when all operations
    // file are supported.
    pub fn new(
        name: String,
        target_unique_id: u64,
        offset_range: Range<u64>,
        start_instant: Instant,
    ) -> TargetType {
        let file = OpenOptions::new().write(true).append(false).open(&name).unwrap();
        Arc::new(Box::new(FileBlockingTarget {
            name,
            file,
            target_unique_id,
            offset_range,
            start_instant,
        }))
    }

    // pwrite the buffer in IoPacket at io_offset_range.
    fn write(&self, io_packet: &mut dyn IoPacket) {
        let offset_range = io_packet.io_offset_range().clone();

        if offset_range.start < self.offset_range.start || offset_range.end > self.offset_range.end
        {
            io_packet.set_error(Error::OffsetOutOfRange);
            return;
        }

        let raw_fd = self.file.as_raw_fd().clone();
        let b = io_packet.buffer_mut();

        let ret = pwrite(raw_fd, b, offset_range.start as i64);
        if let Err(err) = ret {
            return io_packet.set_error(err);
        }
    }

    fn open(&self, io_packet: &mut dyn IoPacket) {
        error!("open not yet supported {}", io_packet.sequence_number());
        process::abort();
    }

    fn exit(&self, io_packet: &mut dyn IoPacket) {
        debug!("Nothing to do for exit path {}", io_packet.sequence_number());
    }
}

impl Target for FileBlockingTarget {
    fn setup(&mut self, _file_name: &String, _range: Range<u64>) -> Result<(), Error> {
        Ok(())
    }

    fn create_io_packet(
        &self,
        operation_type: OperationType,
        seq: u64,
        seed: u64,
        io_offset_range: Range<u64>,
        target: TargetType,
    ) -> IoPacketType {
        Box::new(FileIoPacket::new(operation_type, seq, seed, io_offset_range, target))
    }

    fn id(&self) -> u64 {
        self.target_unique_id
    }

    fn supported_ops() -> &'static TargetOps
    where
        Self: Sized,
    {
        // For now only writes are supported.
        &TargetOps { write: true, open: false }
    }

    fn allowed_ops() -> &'static TargetOps
    where
        Self: Sized,
    {
        // For now only writes are allowed.
        &TargetOps { write: true, open: false }
    }

    fn do_io(&self, io_packet: &mut dyn IoPacket) {
        match io_packet.operation_type() {
            OperationType::Write => self.write(io_packet),
            OperationType::Open => self.open(io_packet),
            OperationType::Exit => self.exit(io_packet),
            _ => {
                error!("Unsupported operation");
                process::abort();
            }
        };
    }

    fn is_complete(&self, io_packet: &dyn IoPacket) -> bool {
        match io_packet.operation_type() {
            OperationType::Write | OperationType::Open | OperationType::Exit => true,
            _ => {
                error!("Complete for unsupported operation");
                process::abort();
            }
        }
    }

    fn verify_needs_io(&self, io_packet: &dyn IoPacket) -> bool {
        match io_packet.operation_type() {
            OperationType::Write | OperationType::Open | OperationType::Exit => false,
            _ => {
                error!("verify_needs_io for unsupported operation");
                process::abort();
            }
        }
    }

    fn generate_verify_io(&self, io_packet: &mut dyn IoPacket) {
        match io_packet.operation_type() {
            _ => {
                error!("generate_verify_io for unsupported operation");
                process::abort();
            }
        };
    }

    fn verify(&self, io_packet: &mut dyn IoPacket, _verify_packet: &dyn IoPacket) -> bool {
        match io_packet.operation_type() {
            OperationType::Write | OperationType::Exit => true,
            _ => {
                error!("verify for unsupported operation");
                process::abort();
            }
        }
    }

    fn start_instant(&self) -> Instant {
        self.start_instant
    }
}

#[cfg(test)]
mod tests {

    use {
        crate::file_target::FileBlockingTarget,
        crate::operations::OperationType,
        crate::target::{Error, TargetType},
        std::{fs, fs::File, time::Instant},
    };

    static FILE_LENGTH: u64 = 1 * 1024 * 1024; // 1 MiB

    fn setup(file_name: &String) -> TargetType {
        let f = File::create(&file_name).unwrap();
        f.set_len(FILE_LENGTH).unwrap();
        let start_instant = Instant::now();
        FileBlockingTarget::new(file_name.to_string(), 0, 0..FILE_LENGTH, start_instant)
    }

    fn teardown(file_name: &String) {
        fs::remove_file(file_name).unwrap();
    }

    #[test]
    fn simple_write() {
        let file_name = "/tmp/odu-file_target-simple_write-file01".to_string();

        let target = setup(&file_name);
        let mut io_packet =
            target.create_io_packet(OperationType::Write, 0, 0, 0..4096, target.clone());
        let mut _buffer = io_packet.buffer_mut();
        io_packet.do_io();
        assert_eq!(io_packet.is_complete(), true);
        io_packet.get_error().unwrap();
        teardown(&file_name);
    }

    #[test]
    fn write_failure() {
        let file_name = "/tmp/odu-file_target-write_failure-file01".to_string();

        let target = setup(&file_name);

        // Try to write beyond allowed offset range
        let mut io_packet = target.create_io_packet(
            OperationType::Write,
            0,
            0,
            (2 * FILE_LENGTH)..(3 * FILE_LENGTH),
            target.clone(),
        );
        let mut _buffer = io_packet.buffer_mut();
        io_packet.do_io();
        assert_eq!(io_packet.is_complete(), true);
        assert_eq!(io_packet.get_error().is_err(), true);
        assert_eq!(io_packet.get_error().err(), Some(Error::OffsetOutOfRange));
        teardown(&file_name);
    }
}
