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

#[cfg(feature = "serde")]
use serde::{de::Deserializer, ser::Serializer, Deserialize, Serialize};
use {
    crate::{error::RightsRoutingError, walk_state::WalkStateUnit},
    fidl_fuchsia_io as fio,
    std::fmt,
};

/// All the fio rights required to represent fio::OpenFlags::RIGHT_READABLE.
const LEGACY_READABLE_RIGHTS: fio::Operations = fio::Operations::empty()
    .union(fio::Operations::READ_BYTES)
    .union(fio::Operations::GET_ATTRIBUTES)
    .union(fio::Operations::TRAVERSE)
    .union(fio::Operations::ENUMERATE);

/// All the fio rights required to represent fio::OpenFlags::RIGHT_WRITABLE.
const LEGACY_WRITABLE_RIGHTS: fio::Operations = fio::Operations::empty()
    .union(fio::Operations::WRITE_BYTES)
    .union(fio::Operations::UPDATE_ATTRIBUTES)
    .union(fio::Operations::MODIFY_DIRECTORY);

/// Opaque rights type to define new traits like PartialOrd on.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct Rights(fio::Operations);

impl Rights {
    /// Converts new fuchsia.io directory rights to legacy fuchsia.io compatible rights. This will
    /// be remove once new rights are supported by component manager.
    pub fn into_legacy(&self) -> fio::OpenFlags {
        let mut flags = fio::OpenFlags::empty();
        let Self(rights) = self;
        // The `intersects` below is intentional. The translation from io2 to io rights is lossy
        // in the sense that a single io2 right may require an io right with coarser permissions.
        if rights.intersects(LEGACY_READABLE_RIGHTS) {
            flags |= fio::OpenFlags::RIGHT_READABLE;
        }
        if rights.intersects(LEGACY_WRITABLE_RIGHTS) {
            flags |= fio::OpenFlags::RIGHT_WRITABLE;
        }
        if rights.contains(fio::Operations::EXECUTE) {
            flags |= fio::OpenFlags::RIGHT_EXECUTABLE;
        }
        flags
    }
}

/// Allows creating rights from fio::Operations.
impl From<fio::Operations> for Rights {
    fn from(operations: fio::Operations) -> Self {
        Rights(operations)
    }
}

impl fmt::Display for Rights {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let Self(rights) = self;
        match *rights {
            fio::R_STAR_DIR => write!(f, "r*"),
            fio::W_STAR_DIR => write!(f, "w*"),
            fio::X_STAR_DIR => write!(f, "x*"),
            fio::RW_STAR_DIR => write!(f, "rw*"),
            fio::RX_STAR_DIR => write!(f, "rx*"),
            ops => write!(f, "{:?}", ops),
        }
    }
}

#[cfg(feature = "serde")]
impl Serialize for Rights {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let Self(rights) = self;
        rights.bits().serialize(serializer)
    }
}

#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for Rights {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let bits: u64 = Deserialize::deserialize(deserializer)?;
        let rights = fio::Operations::from_bits(bits)
            .ok_or(serde::de::Error::custom("invalid value for fuchsia.io/Operations"))?;
        Ok(Self(rights))
    }
}

impl WalkStateUnit for Rights {
    type Error = RightsRoutingError;

    /// Ensures the next walk state of rights satisfies a monotonic increasing sequence. Used to
    /// verify the expectation that no right requested from a use, offer, or expose is missing as
    /// capability routing walks from the capability's consumer to its provider.
    fn validate_next(&self, next_rights: &Rights) -> Result<(), Self::Error> {
        if next_rights.0.contains(self.0) {
            Ok(())
        } else {
            Err(RightsRoutingError::Invalid { requested: *self, provided: *next_rights })
        }
    }

    fn finalize_error() -> Self::Error {
        RightsRoutingError::MissingRightsSource
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use assert_matches::assert_matches;

    /// All the fio rights required to represent fio::OpenFlags::RIGHT_EXECUTABLE.
    const LEGACY_EXECUTABLE_RIGHTS: fio::Operations = fio::Operations::EXECUTE;

    #[test]
    fn validate_next() {
        assert_matches!(
            Rights::from(fio::Operations::empty())
                .validate_next(&Rights::from(LEGACY_READABLE_RIGHTS)),
            Ok(())
        );
        assert_matches!(
            Rights::from(fio::Operations::READ_BYTES | fio::Operations::GET_ATTRIBUTES)
                .validate_next(&Rights::from(LEGACY_READABLE_RIGHTS)),
            Ok(())
        );
        let provided = fio::Operations::READ_BYTES | fio::Operations::GET_ATTRIBUTES;
        assert_eq!(
            Rights::from(LEGACY_READABLE_RIGHTS).validate_next(&Rights::from(provided)),
            Err(RightsRoutingError::Invalid {
                requested: Rights::from(LEGACY_READABLE_RIGHTS),
                provided: Rights::from(provided),
            })
        );
        let provided = fio::Operations::READ_BYTES | fio::Operations::GET_ATTRIBUTES;
        assert_eq!(
            Rights::from(fio::Operations::WRITE_BYTES).validate_next(&Rights::from(provided)),
            Err(RightsRoutingError::Invalid {
                requested: Rights::from(fio::Operations::WRITE_BYTES),
                provided: Rights::from(provided),
            })
        );
    }

    #[test]
    fn into_legacy() {
        assert_eq!(
            Rights::from(LEGACY_READABLE_RIGHTS).into_legacy(),
            fio::OpenFlags::RIGHT_READABLE
        );
        assert_eq!(
            Rights::from(LEGACY_WRITABLE_RIGHTS).into_legacy(),
            fio::OpenFlags::RIGHT_WRITABLE
        );
        assert_eq!(
            Rights::from(LEGACY_EXECUTABLE_RIGHTS).into_legacy(),
            fio::OpenFlags::RIGHT_EXECUTABLE
        );
        assert_eq!(
            Rights::from(LEGACY_READABLE_RIGHTS | LEGACY_WRITABLE_RIGHTS).into_legacy(),
            fio::OpenFlags::RIGHT_READABLE | fio::OpenFlags::RIGHT_WRITABLE
        );
        assert_eq!(
            Rights::from(
                LEGACY_READABLE_RIGHTS | LEGACY_WRITABLE_RIGHTS | LEGACY_EXECUTABLE_RIGHTS
            )
            .into_legacy(),
            fio::OpenFlags::RIGHT_READABLE
                | fio::OpenFlags::RIGHT_WRITABLE
                | fio::OpenFlags::RIGHT_EXECUTABLE
        );
        assert_eq!(
            Rights::from(fio::Operations::READ_BYTES).into_legacy(),
            fio::OpenFlags::RIGHT_READABLE
        );
        assert_eq!(
            Rights::from(fio::Operations::GET_ATTRIBUTES).into_legacy(),
            fio::OpenFlags::RIGHT_READABLE
        );
        assert_eq!(
            Rights::from(fio::Operations::TRAVERSE).into_legacy(),
            fio::OpenFlags::RIGHT_READABLE
        );
        assert_eq!(
            Rights::from(fio::Operations::ENUMERATE).into_legacy(),
            fio::OpenFlags::RIGHT_READABLE
        );
        assert_eq!(
            Rights::from(fio::Operations::WRITE_BYTES).into_legacy(),
            fio::OpenFlags::RIGHT_WRITABLE
        );
        assert_eq!(
            Rights::from(fio::Operations::UPDATE_ATTRIBUTES).into_legacy(),
            fio::OpenFlags::RIGHT_WRITABLE
        );
        assert_eq!(
            Rights::from(fio::Operations::MODIFY_DIRECTORY).into_legacy(),
            fio::OpenFlags::RIGHT_WRITABLE
        );
    }
}
