use std::collections::BTreeSet;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum TreeShellAction {
    Open,
    CreateChild,
    Rename,
    Move,
    ContextMenu,
    Pick,
    AssetOpen,
    ResourceCopy,
    ResourceMove,
    ResourceUpload,
}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct TreeShellActionRegistry {
    pub actions: BTreeSet<TreeShellAction>,
}

impl TreeShellActionRegistry {
    pub fn page_tree() -> Self {
        Self {
            actions: BTreeSet::from([
                TreeShellAction::Open,
                TreeShellAction::CreateChild,
                TreeShellAction::Rename,
                TreeShellAction::Move,
                TreeShellAction::ContextMenu,
            ]),
        }
    }

    pub fn file_tree() -> Self {
        Self {
            actions: BTreeSet::from([
                TreeShellAction::Open,
                TreeShellAction::ContextMenu,
                TreeShellAction::AssetOpen,
                TreeShellAction::ResourceCopy,
                TreeShellAction::ResourceMove,
                TreeShellAction::ResourceUpload,
            ]),
        }
    }

    pub fn picker() -> Self {
        Self {
            actions: BTreeSet::from([TreeShellAction::Pick]),
        }
    }

    pub fn allows(&self, action: TreeShellAction) -> bool {
        self.actions.contains(&action)
    }
}

#[cfg(test)]
mod tests {
    use super::{TreeShellAction, TreeShellActionRegistry};

    #[test]
    fn tree_shell_action_registry_separates_page_filetree_and_picker_actions() {
        let page = TreeShellActionRegistry::page_tree();
        assert!(page.allows(TreeShellAction::CreateChild));
        assert!(!page.allows(TreeShellAction::ResourceUpload));

        let filetree = TreeShellActionRegistry::file_tree();
        assert!(filetree.allows(TreeShellAction::ResourceMove));
        assert!(filetree.allows(TreeShellAction::AssetOpen));
        assert!(!filetree.allows(TreeShellAction::Rename));

        let picker = TreeShellActionRegistry::picker();
        assert!(picker.allows(TreeShellAction::Pick));
        assert!(!picker.allows(TreeShellAction::Open));
    }
}
