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

use {
    crate::io_packet::{IoPacket, IoPacketType},
    crate::operations::OperationType,
    serde::{Deserialize, Serialize},
    std::{io::ErrorKind, ops::Range, result::Result, sync::Arc, time::Instant},
    thiserror::Error,
};

#[derive(Debug, Clone, Error, PartialEq)]
pub enum Error {
    #[error("Offset provided is out of range for the target.")]
    OffsetOutOfRange,

    #[error("Wrote less bytes than requested")]
    ShortWrite,

    #[error("System error while performing IO.")]
    DoIoError(ErrorKind),

    #[error("Read less bytes than requested")]
    ShortRead,
}

#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(test, derive(Hash))]
pub enum AvailableTargets {
    FileTarget,
}

impl AvailableTargets {
    pub fn friendly_names() -> Vec<&'static str> {
        vec![
            "file", // for FileTarget,
        ]
    }

    pub fn friendly_name_to_value(
        name: &str,
    ) -> std::result::Result<AvailableTargets, &'static str> {
        match name {
            "file" => Ok(AvailableTargets::FileTarget),
            _ => Err("invalid target type"),
        }
    }

    pub fn value_to_friendly_name(value: AvailableTargets) -> &'static str {
        match value {
            AvailableTargets::FileTarget => "file",
        }
    }
}

pub type TargetType = Arc<Box<dyn Target + Send + Sync>>;

/// Targets is the object on which IO operations can be performed. Target traits
/// help to create IoPackets, which operate on the. For example files,
/// directories, block devices and blobs can be targets that implement
/// their own way of doing IO.
/// Currently only File blocking IO call are implemented. Some of these
/// functions are no-ops as the work is still in progress.
pub trait Target {
    fn setup(&mut self, file_name: &String, range: Range<u64>) -> Result<(), Error>;

    // TODO(auradkar): This function prototype is weird - it takes self (of type
    // Target) and it also takes TargetType (of type Arc<Box<Target>>). We don't
    // have use for self. All we want is IoPacket to hold a reference over
    // Target throughout IoPackets life span. I am unable to make the code
    // compile without passing both self and TargetType. I need to figure out
    // a way to do this.
    fn create_io_packet(
        &self,
        operation_type: OperationType,
        seq: u64,
        seed: u64,
        io_offset_range: Range<u64>,
        target: TargetType, // &Arc<Box<Target + Send + Sync>>,
    ) -> IoPacketType;

    /// Returns target unique identifier.
    fn id(&self) -> u64;

    /// Returns a reference to a struct which contains all the valid operations
    /// for the instance of the target. See allowed_ops.
    fn supported_ops() -> &'static TargetOps
    where
        Self: Sized;

    /// allowed_ops() is a set of operations that the user is allowed to
    /// request to be measured against this particular kind of target,
    /// while supported_ops() is a set of operations that the generator is
    /// allowed to generate for this target.
    ///
    /// allowed_ops() must be a non-strict subset of supported_ops().
    ///
    /// The reason a generator is allowed to generate operations that are not
    /// allowed for explicit user selection, is because for certain targets
    /// generators may need to follow particular patterns when generating
    /// operations. And we still want to see individual times for those
    /// operations.
    ///
    /// Currently one example is the "truncate" operation on blobfs. "truncate"
    /// can and must only be used on a newly created blobs before any data is
    /// written in the blob. The generator will need to issue "open",
    /// followed by "truncate", when creating a new blob and we want to see
    /// individual times for both operations. At the same time, allowing the
    /// users to request "truncate" based loads is meaningless.
    fn allowed_ops() -> &'static TargetOps
    where
        Self: Sized;

    /// issues an IO
    fn do_io(&self, io_packet: &mut dyn IoPacket);

    /// Returns true if the issued IO is complete.
    fn is_complete(&self, io_packet: &dyn IoPacket) -> bool;

    /// Returns true if verify needs an IO
    fn verify_needs_io(&self, io_packet: &dyn IoPacket) -> bool;

    /// Generates parameters for verify IO packet.
    fn generate_verify_io(&self, io_packet: &mut dyn IoPacket);

    /// Verifies "success" of an IO. Returns true if IO was successful.
    fn verify(&self, io_packet: &mut dyn IoPacket, verify_packet: &dyn IoPacket) -> bool;

    fn start_instant(&self) -> Instant;
}

/// Not all targets implement all operations. For example truncate is meaningless
/// for block device where as readdir is meaningless for posix files. When a
/// structure implements a Target trait, this structure helps to programmatically
/// know what are valid operations for a given Target.
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
pub struct TargetOps {
    pub write: bool,
    pub open: bool,
    pub read: bool,
    //    pub lseek: bool,
    //    pub close: bool,
    //    pub fsync: bool,
    //
    //
    //    pub create: bool,
    //    pub unlink: bool,
    //    pub createdir: bool,
    //    pub deletedir: bool,
    //    pub readdir: bool,
    //    pub opendir: bool,
    //    pub link: bool,
    //
    //    pub mount: bool,
    //    pub unmount: bool,
}

impl TargetOps {
    pub fn friendly_names() -> Vec<&'static str> {
        vec!["write", "read", "open"]
    }

    pub fn enabled(&self, name: &str) -> bool {
        match name {
            "write" => return self.write,
            "read" => return self.read,
            "open" => return self.open,
            _ => false,
        }
    }

    pub fn enabled_operation_names(&self) -> Vec<&'static str> {
        TargetOps::friendly_names().iter().filter(|name| self.enabled(name)).map(|&x| x).collect()
    }

    pub fn enable(&mut self, name: &str, enabled: bool) -> std::result::Result<(), &'static str> {
        match name {
            "write" => self.write = enabled,
            "open" => self.open = enabled,
            "read" => self.read = enabled,
            _ => return Err("Invalid input"),
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use {
        crate::target::{AvailableTargets, TargetOps},
        std::collections::HashSet,
    };

    #[test]
    fn enabled_all_enabled() {
        let x: TargetOps = TargetOps { write: true, open: true, read: true };
        assert!(x.enabled("write"));
        assert!(x.enabled("open"));
        assert!(x.enabled("read"));
    }

    #[test]
    fn enabled_none_enabled() {
        let x: TargetOps = TargetOps { write: false, open: false, read: false };
        assert!(!x.enabled("write"));
        assert!(!x.enabled("open"));
        assert!(!x.enabled("read"));
    }

    #[test]
    fn enable_toggle_one() {
        let mut x: TargetOps = TargetOps { write: false, open: false, read: false };
        assert!(!x.enabled("write"));
        assert!(!x.enabled("open"));
        assert!(!x.enabled("read"));

        x.enable("open", true).unwrap();
        assert!(!x.enabled("write"));
        assert!(!x.enabled("read"));
        assert!(x.enabled("open"));

        x.enable("open", false).unwrap();
        assert!(!x.enabled("write"));
        assert!(!x.enabled("read"));
        assert!(!x.enabled("open"));
    }

    #[test]
    fn friendly_names_count() {
        // Reminds to add more test when number of target types change
        assert_eq!(AvailableTargets::friendly_names().len(), 1);
    }

    #[test]
    fn friendly_names_get_all() {
        // Reminds to add more test when number of target types change
        assert_eq!(AvailableTargets::friendly_names(), vec!["file"]);
    }

    #[test]
    fn all_names_have_unique_values() {
        let names = AvailableTargets::friendly_names();
        let mut values = HashSet::new();

        for name in names.iter() {
            let value = AvailableTargets::friendly_name_to_value(name).unwrap();
            assert_eq!(values.contains(&value), false);
            values.insert(value);
        }
    }

    #[test]
    fn friendly_names_to_value_valid_name() {
        assert_eq!(
            AvailableTargets::friendly_name_to_value("file").unwrap(),
            AvailableTargets::FileTarget
        );
    }

    #[test]
    fn friendly_names_to_value_invalid_name() {
        assert_eq!(AvailableTargets::friendly_name_to_value("hello").is_err(), true);
    }

    #[test]
    fn friendly_names_to_value_null_name() {
        assert_eq!(AvailableTargets::friendly_name_to_value("").is_err(), true);
    }

    #[test]
    fn value_to_friendly_name() {
        assert_eq!(AvailableTargets::value_to_friendly_name(AvailableTargets::FileTarget), "file");
    }
}
