package cli import ( "flag" "fmt" "git.theodohertyfamily.com/tools/wg-wrap/internal/config" ) type App struct { Args []string ConfigDir string // Optional override for profile storage location } func NewApp(args []string) *App { return &App{Args: args} } func (a *App) Run() error { // Handle subcommands first (profile list, import, configure, delete, stop) if len(a.Args) > 1 && a.Args[1] == "profile" { return a.handleProfileCmd() } cfg := &config.Config{} fs := flag.NewFlagSet("wg-wrap", flag.ExitOnError) fs.StringVar(&cfg.Profile, "profile", "", "WireGuard profile to use (filename without extension in ~/.config/wg-wrap/profiles/)") fs.StringVar(&cfg.DNSServer, "dns-server", "", "Override DNS server to use") args := a.Args[1:] sepIdx := -1 for i, arg := range args { if arg == "--" { sepIdx = i break } } var flagsToParse []string if sepIdx != -1 { flagsToParse = args[:sepIdx] cfg.Command = args[sepIdx+1:] } else { flagsToParse = args } err := fs.Parse(flagsToParse) if err != nil { return fmt.Errorf("error parsing flags: %w", err) } if sepIdx == -1 { cfg.Command = fs.Args() } if len(cfg.Command) == 0 { return fmt.Errorf("no command provided. use --help for usage") } if cfg.Profile == "" { cfg.Profile = "default" } profilesDir := a.ConfigDir if profilesDir == "" { profilesDir = config.GetDefaultProfilesDir() } fmt.Printf("Profile: %s\n", cfg.Profile) fmt.Printf("Profiles Directory: %s\n", profilesDir) fmt.Printf("DNS Server: %s\n", cfg.DNSServer) fmt.Printf("Command: %v\n", cfg.Command) return nil } func (a *App) handleProfileCmd() error { if len(a.Args) < 3 { return fmt.Errorf("usage: wg-wrap profile [args]") } subCmd := a.Args[2] switch subCmd { case "list": fmt.Println("Listing profiles...") return fmt.Errorf("profile list not yet implemented") case "import": if len(a.Args) < 4 { return fmt.Errorf("usage: wg-wrap profile import ") } fmt.Printf("Importing profile from %s...\n", a.Args[3]) return fmt.Errorf("profile import not yet implemented") case "configure": if len(a.Args) < 4 { return fmt.Errorf("usage: wg-wrap profile configure ") } fmt.Printf("Configuring profile %s...\n", a.Args[3]) return fmt.Errorf("profile configure not yet implemented") case "delete": if len(a.Args) < 4 { return fmt.Errorf("usage: wg-wrap profile delete ") } fmt.Printf("Deleting profile %s...\n", a.Args[3]) return fmt.Errorf("profile delete not yet implemented") case "stop": if len(a.Args) < 4 { return fmt.Errorf("usage: wg-wrap profile stop ") } fmt.Printf("Stopping profile %s and unpinning namespace...\n", a.Args[3]) return fmt.Errorf("profile stop not yet implemented") default: return fmt.Errorf("unknown profile subcommand: %s", subCmd) } }