From 2cf44bb6ca28be318fb726a5b94e00b8f597d06f Mon Sep 17 00:00:00 2001
From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com>
Date: Thu, 21 Mar 2024 21:20:16 -0400
Subject: [PATCH] (init) modulesmgr commands

---
 src/core/botmodules.rs | 314 ++++++++++++++++++++++++++++++++++++++++-
 src/core/identity.rs   |   2 +-
 2 files changed, 314 insertions(+), 2 deletions(-)

diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs
index fadfdab..fb57dfc 100644
--- a/src/core/botmodules.rs
+++ b/src/core/botmodules.rs
@@ -35,17 +35,132 @@ use tokio::sync::RwLock;
 use async_trait::async_trait;
 
 use self::bot_actions::actions_util::BotAR;
+use crate::core::bot_actions::actions_util;
 use crate::core::botinstance::{BotInstance, ChType,ChangeResult};
 use crate::core::botlog;
-use crate::core::identity;
+use crate::core::identity::{self, Permissible};
 
 use crate::core::bot_actions;
 pub use ChType::Channel;
 pub use ModType::BotModule;
 
+use super::identity::ChatBadge;
+
 // use super::identity::ChangeResult;
 
 
+pub async fn init(mgr: Arc<ModulesManager>) {
+
+    const OF_CMD_CHANNEL:ChType = Channel(String::new());
+
+    // 1. Define the BotAction
+    let botc1 = BotCommand {
+        module: BotModule(String::from("core")),
+        command: String::from("enable"), // command call name
+        alias: vec![
+            String::from("e"), 
+            String::from("en")], // String of alternative names
+        exec_body: actions_util::asyncbox(cmd_enable),
+        help: String::from("Test Command tester"),
+        required_roles: vec![
+            identity::UserRole::BotAdmin,
+            identity::UserRole::Mod(OF_CMD_CHANNEL),
+            identity::UserRole::SupMod(OF_CMD_CHANNEL),
+            identity::UserRole::Broadcaster,
+        ], 
+    };
+
+    // 2. Add the BotAction to ModulesManager
+    botc1.add_core_to_modmgr(Arc::clone(&mgr)).await;
+    
+    async fn cmd_enable(bot: BotAR, msg: PrivmsgMessage) {
+        /*
+            There should be additional validation checks
+            - BotAdmins can only run instance level (-i) enables
+            - If BotAdmins need to enable/disable at instance level, they must Promote themselves to be a Mod at least
+            - Other Special Roles (Mod,SupMod,Broadcaster) can run without issues to enable the module at Channel Level
+         */
+
+        /*
+            enable -i <module> // enables at Instance
+            enable <module> // enables at Channel
+         */
+
+        /*
+
+            1. Parse out Message Arguments
+
+            
+            exec_enable()
+
+            2. Get Special Roles of CmdSender
+            3. If CmdSender is BotAdmin but not (Mod,SupMod,Broadcaster) 
+                3a. , and is not -i (to instance) , return a Failure recommending BotAdmin promote themselves first
+                3b. , and is -i (to instance) , return a Success
+            4. If CmdSender not a BotAdmin but is (Mod,SupMod,Broadcaster) 
+                4a. , and is not -i (to instance) , return a Success
+                4b. , and is -i (to instance) , return a Failure they are not allowed
+            5. If CmdSender is (Mod,SupMod,Broadcaster) and a BotAdmin 
+                5a. , and is not -i (to instance) , return a Success
+                5b. , and is -i (to instance) , return a Success
+
+         */
+
+
+        /*
+        exec_enable(Self,requestor,requestor_badge,trg_module,Channel) -> ChangeResult
+        */
+
+
+    }
+
+
+
+    // 1. Define the BotAction
+    let botc1 = BotCommand {
+        module: BotModule(String::from("core")),
+        command: String::from("disable"), // command call name
+        alias: vec![
+            String::from("d")], // String of alternative names
+        exec_body: actions_util::asyncbox(cmd_disable),
+        help: String::from("Test Command tester"),
+        required_roles: vec![
+            identity::UserRole::BotAdmin,
+            identity::UserRole::Mod(OF_CMD_CHANNEL),
+            identity::UserRole::SupMod(OF_CMD_CHANNEL),
+            identity::UserRole::Broadcaster,
+        ], 
+    };
+
+    // 2. Add the BotAction to ModulesManager
+    botc1.add_core_to_modmgr(Arc::clone(&mgr)).await;
+    
+    async fn cmd_disable(bot: BotAR, msg: PrivmsgMessage) {
+        /*
+            There should be additional validation checks
+            - BotAdmins can only run instance level (-i) disables
+            - If BotAdmins need to enable/disable at instance level, they must Promote themselves to be a Mod at least
+            - Other Special Roles (Mod,SupMod,Broadcaster) can run without issues to disable the module at Channel Level
+            */
+
+        /*
+            disable -i <module> // disables at Instance
+            disable <module> // disables at Channel
+            disable -f <module> // force disables (instance and enabled are removed)
+         */
+
+
+    }
+
+
+}
+
+
+
+
+
+
+
 #[derive(Debug, PartialEq, Eq, Hash, Clone)]
 pub enum ModType {
     BotModule(String),
@@ -332,6 +447,203 @@ impl ModulesManager {
     //     Ok("")
     // }
 
+        /*
+        exec_enable(self,requestor,requestor_badge,trg_module,Channel) -> ChangeResult
+        */
+
+    pub async fn exec_enable(
+        &self,
+        requestor: String,
+        requestor_badge: Option<ChatBadge>,
+        trg_module: ModType,
+        // channel: Option<ChType>,
+        trg_level: StatusLvl,
+        bot: BotAR,
+    ) -> ChangeResult 
+    {
+
+        /*
+        
+            1. If CmdSender is BotAdmin but not (Mod,SupMod,Broadcaster)
+            1. can_user_run for cmdreqRoles including BotAdmin & not can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) 
+                1a. , and is not -i (to instance) , return a Failure recommending BotAdmin promote themselves first
+                1b. , and is -i (to instance) , return a Success
+            
+            2. If CmdSender not a BotAdmin but is (Mod,SupMod,Broadcaster) 
+            2. not can_user_run for cmdreqRoles including BotAdmin & can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) 
+                2a. , and is not -i (to instance) , return a Success
+                2b. , and is -i (to instance) ,  return a Failure they are not allowed
+
+            3. If CmdSender is (Mod,SupMod,Broadcaster) and a BotAdmin 
+            3. can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) & can_user_run for cmdreqRoles including BotAdmin
+                3a. , and is not -i (to instance) , return a Success
+                3b. , and is -i (to instance) , return a Success    
+         */
+
+
+         /*
+            [ ] 1. If CmdSender is BotAdmin but not (Mod,SupMod,Broadcaster)
+                1. can_user_run for cmdreqRoles including BotAdmin & not can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) 
+                    1a. , and is -i (to instance) , return a Success
+                    1b. , and is not -i (to instance) , return a Failure recommending BotAdmin promote themselves first
+
+            
+          */
+
+
+        let botlock = bot.read().await;
+        let id = botlock.get_identity();
+        let mut idlock = id.write().await;
+
+        // if trg_level = StatusLvl::Instance , the temp_chnl = the broadcaster's or the chatter's
+
+        let arb_chnl = match trg_level.clone() {
+            StatusLvl::Instance => ChType::Channel(requestor.to_lowercase()),
+            StatusLvl::Ch(a) => a,
+        };
+
+        const OF_CMD_CHANNEL:ChType = Channel(String::new());
+        
+        let (admin_level_access,_) = idlock.can_user_run(requestor.clone(), arb_chnl.clone(), requestor_badge.clone(), 
+        vec![
+            identity::UserRole::BotAdmin,
+        ]).await;
+
+
+        let (chnl_elevated_access,_) = idlock.can_user_run(requestor, arb_chnl, requestor_badge.clone(), 
+        vec![
+            identity::UserRole::Mod(OF_CMD_CHANNEL),
+            identity::UserRole::SupMod(OF_CMD_CHANNEL),
+            identity::UserRole::Broadcaster,
+        ]).await;
+
+        if let Permissible::Allow = admin_level_access {
+            if let Permissible::Block = chnl_elevated_access {
+                match trg_level {
+                    StatusLvl::Instance => {
+                        self.set_instance_enabled(trg_module.clone()).await;
+                        ChangeResult::Success("Enabled at Instance Level".to_string())
+                    },
+                    StatusLvl::Ch(_) => {
+                        ChangeResult::Failed("Promote yourself Temporarily First".to_string())
+                    },
+                };
+            }
+        }
+
+
+        /*
+            [ ] 2. If CmdSender not a BotAdmin but is (Mod,SupMod,Broadcaster) 
+                2. not can_user_run for cmdreqRoles including BotAdmin & can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) 
+                    2a. , and is -i (to instance) ,  return a Failure they are not allowed
+                    2b. , and is not -i (to instance) , return a Success
+
+         */
+
+        if let Permissible::Block = admin_level_access {
+            if let Permissible::Allow = chnl_elevated_access {
+                match trg_level.clone() {
+                    StatusLvl::Instance => {
+                        ChangeResult::Failed("You're not allowed".to_string())
+                    },
+                    StatusLvl::Ch(in_chnl) => {
+                        self.set_ch_enabled(trg_module.clone(), in_chnl).await;
+                        ChangeResult::Success("Enabled at Channel Level".to_string())
+                    },
+                };
+            }
+        }
+
+
+        /*
+        
+            [ ] 3. If CmdSender is (Mod,SupMod,Broadcaster) and a BotAdmin 
+                3. can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) & can_user_run for cmdreqRoles including BotAdmin
+                    3a. , and is not -i (to instance) , return a Success
+                    3b. , and is -i (to instance) , return a Success    
+         */
+
+
+         if let Permissible::Allow = admin_level_access {
+            if let Permissible::Allow = chnl_elevated_access {
+                match trg_level {
+                    StatusLvl::Instance => {
+                        self.set_instance_enabled(trg_module.clone()).await;
+                        ChangeResult::Success("Enabled at Instance Level".to_string())
+                    },
+                    StatusLvl::Ch(in_chnl) => {
+                        self.set_ch_enabled(trg_module.clone(), in_chnl).await;
+                        ChangeResult::Success("Enabled at Channel Level".to_string())
+                    },
+                };
+            }
+        }
+
+
+
+
+        // =======================
+
+        // =======================
+
+        // =======================
+
+
+        // /*
+        
+        //     2. Get Special Roles of CmdSender
+        //     3. If CmdSender is BotAdmin but not (Mod,SupMod,Broadcaster) 
+        //         3a. , and is not -i (to instance) , return a Failure recommending BotAdmin promote themselves first
+        //         3b. , and is -i (to instance) , return a Success
+        //     4. If CmdSender not a BotAdmin but is (Mod,SupMod,Broadcaster) 
+        //         4a. , and is not -i (to instance) , return a Success
+        //         4b. , and is -i (to instance) , return a Failure they are not allowed
+        //     5. If CmdSender is (Mod,SupMod,Broadcaster) and a BotAdmin 
+        //         5a. , and is not -i (to instance) , return a Success
+        //         5b. , and is -i (to instance) , return a Success
+
+        
+        // */
+
+        // // [ ] 2. Get Special Roles of CmdSender
+
+        // let botlock = bot.read().await;
+        // let id = botlock.get_identity();
+        // let idlock = id.read().await;
+
+
+        // let trgchnl = {
+        //     match trg_level {
+        //         StatusLvl::Instance => None,
+        //         StatusLvl::Ch(a) => Some(a),
+        //     }
+        // };
+
+        // let requestor_roles = idlock
+        //         .getspecialuserroles(
+        //             requestor.to_lowercase(),
+        //             trgchnl,
+        //         )
+        //         .await;
+
+        // /*
+        //     [ ] 3. If CmdSender is BotAdmin but not (Mod,SupMod,Broadcaster) 
+        //         3a. , and is not -i (to instance) , return a Failure recommending BotAdmin promote themselves first
+        //         3b. , and is -i (to instance) , return a Success
+        //  */
+        
+        // if requestor_roles.contains(&identity::UserRole::BotAdmin) 
+        //     && !requestor_roles.contains(&identity::UserRole::Broadcaster)
+        //     && !requestor_roles.contains(&identity::UserRole::Mod(trgchnl)) 
+        // {
+
+        // } 
+
+
+
+        ChangeResult::NoChange("ERROR : Not implemented yet".to_string())
+    }
+
     pub async fn set_instance_disabled(&self, in_module: ModType) -> (StatusType,ChangeResult) {
         // at Instance level
         // - If core module, do nothing
diff --git a/src/core/identity.rs b/src/core/identity.rs
index 65a5088..84905cc 100644
--- a/src/core/identity.rs
+++ b/src/core/identity.rs
@@ -602,7 +602,7 @@ pub struct IdentityManager {
         >
 */
 
-#[derive(Debug)]
+#[derive(Debug, Clone)]
 pub enum ChatBadge {
     Broadcaster,
     Mod,