/// permission for app operations on the Ordinary Server
#[derive(Clone)]
pub enum Permission {
    /// all
    Admin,
    /// logs, list items, list accounts, list apps
    Read,
    /// write assets
    Write,
    /// update content
    Update,
    /// upload templates
    Upload,
    /// install actions
    Install,
    /// deploy, patch and migrate applications
    Deploy,
    /// bridge applications on two separate instances
    Bridge,
    /// kill application
    Kill,
    /// erase the application
    Erase,
}

impl Permission {
    pub fn as_u8(&self) -> u8 {
        match self {
            Self::Admin => 0,
            Self::Read => 1,
            Self::Write => 2,
            Self::Update => 3,
            Self::Upload => 4,
            Self::Install => 5,
            Self::Deploy => 6,
            Self::Bridge => 7,
            Self::Kill => 8,
            Self::Erase => 9,
        }
    }

    pub fn from_u8(n: u8) -> Permission {
        match n {
            0 => Self::Admin,
            1 => Self::Read,
            2 => Self::Write,
            3 => Self::Update,
            4 => Self::Upload,
            5 => Self::Install,
            6 => Self::Deploy,
            7 => Self::Bridge,
            8 => Self::Kill,
            9 => Self::Erase,
            _ => unreachable!(),
        }
    }

    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Admin => "admin",
            Self::Read => "read",
            Self::Write => "write",
            Self::Update => "update",
            Self::Upload => "upload",
            Self::Install => "install",
            Self::Deploy => "deploy",
            Self::Bridge => "bridge",
            Self::Kill => "kill",
            Self::Erase => "erase",
        }
    }
}

impl clap::ValueEnum for Permission {
    fn value_variants<'a>() -> &'a [Self] {
        &[
            Self::Admin,
            Self::Read,
            Self::Write,
            Self::Update,
            Self::Upload,
            Self::Install,
            Self::Deploy,
            Self::Bridge,
            Self::Kill,
            Self::Erase,
        ]
    }

    fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
        match self {
            Self::Admin => Some(clap::builder::PossibleValue::new("admin")),
            Self::Read => Some(clap::builder::PossibleValue::new("read")),
            Self::Write => Some(clap::builder::PossibleValue::new("write")),
            Self::Update => Some(clap::builder::PossibleValue::new("update")),
            Self::Upload => Some(clap::builder::PossibleValue::new("upload")),
            Self::Install => Some(clap::builder::PossibleValue::new("install")),
            Self::Deploy => Some(clap::builder::PossibleValue::new("deploy")),
            Self::Bridge => Some(clap::builder::PossibleValue::new("bridge")),
            Self::Kill => Some(clap::builder::PossibleValue::new("kill")),
            Self::Erase => Some(clap::builder::PossibleValue::new("erase")),
        }
    }
}
