// 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::model::walk_state::WalkStateUnit,
    fidl_fuchsia_io::{self as fio},
    fidl_fuchsia_io2::{self as fio2},
    fuchsia_zircon as zx,
    lazy_static::lazy_static,
    std::convert::From,
    thiserror::Error,
};

lazy_static! {
    // TODO: const initialization of bitflag types with bitwise-or is not supported in FIDL. Change
    // when supported.
    /// All rights corresponding to r*.
    pub static ref READ_RIGHTS: fio2::Operations =
        fio2::Operations::Connect
        | fio2::Operations::Enumerate
        | fio2::Operations::Traverse
        | fio2::Operations::ReadBytes
        | fio2::Operations::GetAttributes;
    /// All rights corresponding to w*.
    pub static ref WRITE_RIGHTS: fio2::Operations =
        fio2::Operations::Connect
        | fio2::Operations::Enumerate
        | fio2::Operations::Traverse
        | fio2::Operations::WriteBytes
        | fio2::Operations::ModifyDirectory
        | fio2::Operations::UpdateAttributes;

    /// All the fio2 rights required to represent fio::OPEN_RIGHT_READABLE.
    static ref LEGACY_READABLE_RIGHTS: fio2::Operations =
        fio2::Operations::ReadBytes
        | fio2::Operations::GetAttributes
        | fio2::Operations::Traverse
        | fio2::Operations::Enumerate;
    /// All the fio2 rights required to represent fio::OPEN_RIGHT_WRITABLE.
    static ref LEGACY_WRITABLE_RIGHTS: fio2::Operations =
        fio2::Operations::WriteBytes
        | fio2::Operations::UpdateAttributes
        | fio2::Operations::ModifyDirectory;
    /// All the fio2 rights required to represent fio::OPEN_RIGHT_EXECUTABLE.
    static ref LEGACY_EXECUTABLE_RIGHTS: fio2::Operations = fio2::Operations::Execute;
}

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

impl Rights {
    /// Converts fuchsia.io2 directory rights to fuchsia.io compatible rights. This will be removed
    /// once fuchsia.io2 is supported by component manager.
    pub fn into_legacy(&self) -> u32 {
        let mut flags: u32 = 0;
        let rights = self.0;
        // 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::OPEN_RIGHT_READABLE;
        }
        if rights.intersects(*LEGACY_WRITABLE_RIGHTS) {
            flags |= fio::OPEN_RIGHT_WRITABLE;
        }
        if rights.contains(fio2::Operations::Execute) {
            flags |= fio::OPEN_RIGHT_EXECUTABLE;
        }
        if rights.contains(fio2::Operations::Admin) {
            flags |= fio::OPEN_RIGHT_ADMIN;
        }
        // Since there is no direct translation for connect in CV1 we must explicitly define it
        // here as both flags.
        //
        // TODO(fxbug.dev/60673): Is this correct? ReadBytes | Connect seems like it should translate to
        // READABLE | WRITABLE, not empty rights.
        if flags == 0 && rights.contains(fio2::Operations::Connect) {
            flags |= fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_WRITABLE;
        }
        flags
    }
}

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

#[derive(Debug, Error, Clone)]
pub enum RightsError {
    #[error("Requested rights greater than provided rights")]
    Invalid,

    #[error("Directory routes must end at source with a rights declaration")]
    InvalidFinalize,
}

impl RightsError {
    /// Convert this error into its approximate `zx::Status` equivalent.
    pub fn as_zx_status(&self) -> zx::Status {
        zx::Status::UNAVAILABLE
    }
}

impl WalkStateUnit for Rights {
    type Error = RightsError;

    /// 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(RightsError::Invalid)
        }
    }

    fn finalize_error() -> Self::Error {
        RightsError::InvalidFinalize
    }
}

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

    #[test]
    fn validate_next() {
        assert_matches!(
            Rights::from(fio2::Operations::empty())
                .validate_next(&Rights::from(*LEGACY_READABLE_RIGHTS)),
            Ok(())
        );
        assert_matches!(
            Rights::from(fio2::Operations::ReadBytes | fio2::Operations::GetAttributes)
                .validate_next(&Rights::from(*LEGACY_READABLE_RIGHTS)),
            Ok(())
        );
        assert_matches!(
            Rights::from(Rights::from(*LEGACY_READABLE_RIGHTS)).validate_next(&Rights::from(
                fio2::Operations::ReadBytes | fio2::Operations::GetAttributes
            )),
            Err(RightsError::Invalid)
        );
        assert_matches!(
            Rights::from(fio2::Operations::WriteBytes).validate_next(&Rights::from(
                fio2::Operations::ReadBytes | fio2::Operations::GetAttributes
            )),
            Err(RightsError::Invalid)
        );
    }

    #[test]
    fn into_legacy() {
        assert_eq!(Rights::from(*LEGACY_READABLE_RIGHTS).into_legacy(), fio::OPEN_RIGHT_READABLE);
        assert_eq!(Rights::from(*LEGACY_WRITABLE_RIGHTS).into_legacy(), fio::OPEN_RIGHT_WRITABLE);
        assert_eq!(
            Rights::from(*LEGACY_EXECUTABLE_RIGHTS).into_legacy(),
            fio::OPEN_RIGHT_EXECUTABLE
        );
        assert_eq!(
            Rights::from(*LEGACY_READABLE_RIGHTS | *LEGACY_WRITABLE_RIGHTS).into_legacy(),
            fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_WRITABLE
        );
        assert_eq!(
            Rights::from(
                *LEGACY_READABLE_RIGHTS | *LEGACY_WRITABLE_RIGHTS | *LEGACY_EXECUTABLE_RIGHTS
            )
            .into_legacy(),
            fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_WRITABLE | fio::OPEN_RIGHT_EXECUTABLE
        );
        assert_eq!(
            Rights::from(fio2::Operations::ReadBytes).into_legacy(),
            fio::OPEN_RIGHT_READABLE
        );
        assert_eq!(
            Rights::from(fio2::Operations::GetAttributes).into_legacy(),
            fio::OPEN_RIGHT_READABLE
        );
        assert_eq!(
            Rights::from(fio2::Operations::Traverse).into_legacy(),
            fio::OPEN_RIGHT_READABLE
        );
        assert_eq!(
            Rights::from(fio2::Operations::Enumerate).into_legacy(),
            fio::OPEN_RIGHT_READABLE
        );
        assert_eq!(
            Rights::from(fio2::Operations::WriteBytes).into_legacy(),
            fio::OPEN_RIGHT_WRITABLE
        );
        assert_eq!(
            Rights::from(fio2::Operations::UpdateAttributes).into_legacy(),
            fio::OPEN_RIGHT_WRITABLE
        );
        assert_eq!(
            Rights::from(fio2::Operations::ModifyDirectory).into_legacy(),
            fio::OPEN_RIGHT_WRITABLE
        );
    }
}
