package cmd import ( "fmt" "os" "text/tabwriter" "github.com/frenocorp/pop/internal/accounts" "github.com/spf13/cobra" ) func accountsCmd() *cobra.Command { cmd := &cobra.Command{ Use: "accounts", Short: "Manage multiple ProtonMail accounts", Long: `Add, list, switch, and remove named ProtonMail account profiles.`, } cmd.AddCommand(accountsListCmd()) cmd.AddCommand(accountsAddCmd()) cmd.AddCommand(accountsRemoveCmd()) cmd.AddCommand(accountsDefaultCmd()) cmd.AddCommand(accountsShowCmd()) return cmd } func accountsListCmd() *cobra.Command { return &cobra.Command{ Use: "list", Short: "List all configured accounts", Long: `Show all saved ProtonMail account profiles.`, RunE: func(cmd *cobra.Command, args []string) error { store, err := accounts.NewAccountsStore() if err != nil { return fmt.Errorf("failed to create accounts store: %w", err) } accts, err := store.LoadAccounts() if err != nil { return fmt.Errorf("failed to load accounts: %w", err) } if len(accts) == 0 { fmt.Println("No accounts configured. Use 'pop accounts add' to create one.") return nil } w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) fmt.Fprintln(w, "Name\tEmail\tDefault\tAPI Base\tCreated") fmt.Fprintln(w, "----\t-----\t-------\t--------\t-------") for _, acc := range accts { def := "-" if acc.Default { def = "*" } fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", acc.Name, acc.Email, def, acc.APIBaseURL, acc.CreatedAt) } return w.Flush() }, } } func accountsAddCmd() *cobra.Command { var name, email, apiURL string var isDefault bool cmd := &cobra.Command{ Use: "add ", Short: "Add a new account profile", Long: `Add a named ProtonMail account profile for multi-account support.`, Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { accountName := name if len(args) > 0 && args[0] != "" { accountName = args[0] } if accountName == "" { return fmt.Errorf("account name is required") } if email == "" { return fmt.Errorf("email is required (--email)") } store, err := accounts.NewAccountsStore() if err != nil { return fmt.Errorf("failed to create accounts store: %w", err) } if err := store.AddAccount(accountName, email, apiURL, isDefault); err != nil { return fmt.Errorf("failed to add account: %w", err) } fmt.Printf("Added account: %s (%s)\n", accountName, email) if isDefault { fmt.Println("Set as default account") } return nil }, } cmd.Flags().StringVar(&name, "name", "", "Account name (or pass as positional argument)") cmd.Flags().StringVarP(&email, "email", "e", "", "ProtonMail email address") cmd.Flags().StringVar(&apiURL, "api-url", "", "Custom API base URL") cmd.Flags().BoolVarP(&isDefault, "default", "d", false, "Set as default account") _ = cmd.MarkFlagRequired("email") return cmd } func accountsRemoveCmd() *cobra.Command { return &cobra.Command{ Use: "remove ", Short: "Remove an account profile", Long: `Remove a named ProtonMail account profile.`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { accountName := args[0] store, err := accounts.NewAccountsStore() if err != nil { return fmt.Errorf("failed to create accounts store: %w", err) } if err := store.RemoveAccount(accountName); err != nil { return fmt.Errorf("failed to remove account: %w", err) } fmt.Printf("Removed account: %s\n", accountName) return nil }, } } func accountsDefaultCmd() *cobra.Command { var setName string cmd := &cobra.Command{ Use: "default [name]", Short: "Get or set the default account", Long: `Show the current default account, or set a new default.`, Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { store, err := accounts.NewAccountsStore() if err != nil { return fmt.Errorf("failed to create accounts store: %w", err) } if setName == "" && len(args) > 0 { setName = args[0] } if setName != "" { if err := store.SetDefaultAccount(setName); err != nil { return fmt.Errorf("failed to set default account: %w", err) } fmt.Printf("Set default account to: %s\n", setName) return nil } acct, err := store.GetAccount("") if err != nil { return fmt.Errorf("no default account: %w", err) } fmt.Printf("Default account: %s (%s)\n", acct.Name, acct.Email) return nil }, } cmd.Flags().StringVar(&setName, "set", "", "Set default account to this name") return cmd } func accountsShowCmd() *cobra.Command { return &cobra.Command{ Use: "show ", Short: "Show account details", Long: `Display details for a specific account profile.`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { accountName := args[0] store, err := accounts.NewAccountsStore() if err != nil { return fmt.Errorf("failed to create accounts store: %w", err) } acct, err := store.GetAccount(accountName) if err != nil { return fmt.Errorf("failed to get account: %w", err) } fmt.Printf("Name: %s\n", acct.Name) fmt.Printf("Email: %s\n", acct.Email) fmt.Printf("UID: %s\n", acct.UID) fmt.Printf("API Base: %s\n", acct.APIBaseURL) fmt.Printf("Default: %t\n", acct.Default) fmt.Printf("Created: %s\n", acct.CreatedAt) if acct.LastUsedAt != "" { fmt.Printf("Last Used: %s\n", acct.LastUsedAt) } return nil }, } }