// 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::io_packet::{IoPacket, IoPacketType, TimeInterval},
    crate::operations::TargetType,
    crate::operations::{OperationType, PipelineStages, Target, TargetOps},
    libc::{c_void, pwrite},
    log::debug,
    log::error,
    std::{
        fs::{File, OpenOptions},
        io::{Error, ErrorKind, Result},
        ops::Range,
        os::unix::io::AsRawFd,
        process,
        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<ErrorKind>,

    // 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_duration(&self, stage: PipelineStages) -> u128 {
        self.stage_timestamps[stage.stage_number()].duration()
    }

    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: &IoPacket) -> bool {
        self.target.clone().verify(self, verify_packet)
    }

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

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

    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,

    /// Set of [supported] operations
    ops: TargetOps,

    /// 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 ops = TargetOps { write: true, open: true };
        let file = OpenOptions::new().write(true).append(false).open(&name).unwrap();
        Arc::new(Box::new(FileBlockingTarget {
            name,
            file,
            ops,
            target_unique_id,
            offset_range,
            start_instant,
        }))
    }

    // pwrite the buffer in IoPacket at io_offset_range.
    fn write(&self, io_packet: &mut 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::new(ErrorKind::AddrInUse, "Offset out of range!"));
            return;
        }

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

        let ret = unsafe {
            pwrite(raw_fd, b.as_ptr() as *const c_void, b.len(), offset_range.start as i64)
        };
        debug!("do_write: {:?} {}", offset_range, ret);
        if ret < 0 {
            io_packet.set_error(Error::last_os_error());
        } else if ret < b.len() as isize {
            // TODO(auradkar): Define a set of error codes to be used throughout the app.
            io_packet
                .set_error(Error::new(ErrorKind::Other, "pwrite wrote less bytes than requested!"));
        }
    }

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

    fn exit(&self, io_packet: &mut 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<()> {
        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(&self) -> &TargetOps {
        &self.ops
    }

    fn do_io(&self, io_packet: &mut 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: &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: &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 IoPacket) {
        match io_packet.operation_type() {
            _ => {
                error!("generate_verify_io for unsupported operation");
                process::abort();
            }
        };
    }

    fn verify(&self, io_packet: &mut IoPacket, _verify_packet: &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::operations::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/FileBlockingTargetTestFile".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/FileBlockingTargetTestFile2".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);
        teardown(&file_name);
    }
}
