package main import ( "encoding/json" "fmt" "net/http" "strings" "time" ) // handleGroup dispatches group management sub-commands func (c *KVSClient) handleGroup(args []string) { if len(args) == 0 { fmt.Println(red("Usage: group [options]")) return } subCmd := args[0] switch subCmd { case "create": c.handleGroupCreate(args[1:]) case "get": c.handleGroupGet(args[1:]) case "update": c.handleGroupUpdate(args[1:]) case "delete": c.handleGroupDelete(args[1:]) case "add-member": c.handleGroupAddMember(args[1:]) case "remove-member": c.handleGroupRemoveMember(args[1:]) default: fmt.Println(red("Unknown group command:"), subCmd) fmt.Println("Available commands: create, get, update, delete, add-member, remove-member") } } // handleGroupCreate creates a new group func (c *KVSClient) handleGroupCreate(args []string) { if len(args) < 1 { fmt.Println(red("Usage: group create [member-uuid1,member-uuid2,...]")) return } groupname := args[0] var members []string // Parse optional members list if len(args) >= 2 { members = strings.Split(args[1], ",") } payload := map[string]interface{}{ "groupname": groupname, } if len(members) > 0 { payload["members"] = members } respBody, status, err := c.doRequest("POST", "/api/groups", payload) if err != nil { fmt.Println(red("Error:"), err) return } if status != http.StatusOK { fmt.Printf(red("Error creating group (status %d):\n"), status) fmt.Println(string(respBody)) return } var response struct { UUID string `json:"uuid"` } if err := json.Unmarshal(respBody, &response); err != nil { fmt.Println(red("Error parsing response:"), err) return } fmt.Println(green("Group created successfully")) fmt.Println(cyan("UUID:"), response.UUID) } // handleGroupGet retrieves group details func (c *KVSClient) handleGroupGet(args []string) { if len(args) < 1 { fmt.Println(red("Usage: group get ")) return } groupUUID := args[0] respBody, status, err := c.doRequest("GET", "/api/groups/"+groupUUID, nil) if err != nil { fmt.Println(red("Error:"), err) return } if status == http.StatusNotFound { fmt.Println(yellow("Group not found")) return } if status != http.StatusOK { fmt.Printf(red("Error getting group (status %d):\n"), status) fmt.Println(string(respBody)) return } var group Group if err := json.Unmarshal(respBody, &group); err != nil { fmt.Println(red("Error parsing response:"), err) return } fmt.Println(cyan("Group Details:")) fmt.Printf(" UUID: %s\n", group.UUID) fmt.Printf(" Name Hash: %s\n", group.NameHash) fmt.Printf(" Members: %v\n", group.Members) fmt.Printf(" Created: %s\n", time.Unix(group.CreatedAt, 0).Format(time.RFC3339)) fmt.Printf(" Updated: %s\n", time.Unix(group.UpdatedAt, 0).Format(time.RFC3339)) } // handleGroupUpdate replaces all members in a group func (c *KVSClient) handleGroupUpdate(args []string) { if len(args) < 2 { fmt.Println(red("Usage: group update ")) fmt.Println("Note: This replaces ALL members. Use add-member/remove-member for incremental changes.") return } groupUUID := args[0] members := strings.Split(args[1], ",") payload := map[string]interface{}{ "members": members, } respBody, status, err := c.doRequest("PUT", "/api/groups/"+groupUUID, payload) if err != nil { fmt.Println(red("Error:"), err) return } if status == http.StatusNotFound { fmt.Println(yellow("Group not found")) return } if status != http.StatusOK { fmt.Printf(red("Error updating group (status %d):\n"), status) fmt.Println(string(respBody)) return } fmt.Println(green("Group updated successfully")) } // handleGroupDelete deletes a group func (c *KVSClient) handleGroupDelete(args []string) { if len(args) < 1 { fmt.Println(red("Usage: group delete ")) return } groupUUID := args[0] respBody, status, err := c.doRequest("DELETE", "/api/groups/"+groupUUID, nil) if err != nil { fmt.Println(red("Error:"), err) return } if status == http.StatusNotFound { fmt.Println(yellow("Group not found")) return } if status != http.StatusOK { fmt.Printf(red("Error deleting group (status %d):\n"), status) fmt.Println(string(respBody)) return } fmt.Println(green("Group deleted successfully")) } // handleGroupAddMember adds a member to an existing group func (c *KVSClient) handleGroupAddMember(args []string) { if len(args) < 2 { fmt.Println(red("Usage: group add-member ")) return } groupUUID := args[0] userUUID := args[1] // First, get current members respBody, status, err := c.doRequest("GET", "/api/groups/"+groupUUID, nil) if err != nil { fmt.Println(red("Error:"), err) return } if status != http.StatusOK { fmt.Printf(red("Error getting group (status %d):\n"), status) fmt.Println(string(respBody)) return } var group Group if err := json.Unmarshal(respBody, &group); err != nil { fmt.Println(red("Error parsing response:"), err) return } // Check if user is already a member for _, member := range group.Members { if member == userUUID { fmt.Println(yellow("User is already a member of this group")) return } } // Add new member group.Members = append(group.Members, userUUID) // Update group with new members list payload := map[string]interface{}{ "members": group.Members, } respBody, status, err = c.doRequest("PUT", "/api/groups/"+groupUUID, payload) if err != nil { fmt.Println(red("Error:"), err) return } if status != http.StatusOK { fmt.Printf(red("Error updating group (status %d):\n"), status) fmt.Println(string(respBody)) return } fmt.Println(green("Member added successfully")) } // handleGroupRemoveMember removes a member from an existing group func (c *KVSClient) handleGroupRemoveMember(args []string) { if len(args) < 2 { fmt.Println(red("Usage: group remove-member ")) return } groupUUID := args[0] userUUID := args[1] // First, get current members respBody, status, err := c.doRequest("GET", "/api/groups/"+groupUUID, nil) if err != nil { fmt.Println(red("Error:"), err) return } if status != http.StatusOK { fmt.Printf(red("Error getting group (status %d):\n"), status) fmt.Println(string(respBody)) return } var group Group if err := json.Unmarshal(respBody, &group); err != nil { fmt.Println(red("Error parsing response:"), err) return } // Remove member from list newMembers := []string{} found := false for _, member := range group.Members { if member != userUUID { newMembers = append(newMembers, member) } else { found = true } } if !found { fmt.Println(yellow("User is not a member of this group")) return } // Update group with new members list payload := map[string]interface{}{ "members": newMembers, } respBody, status, err = c.doRequest("PUT", "/api/groups/"+groupUUID, payload) if err != nil { fmt.Println(red("Error:"), err) return } if status != http.StatusOK { fmt.Printf(red("Error updating group (status %d):\n"), status) fmt.Println(string(respBody)) return } fmt.Println(green("Member removed successfully")) }