package main import ( "errors" "flag" "fmt" "os" "os/signal" "slices" "syscall" "git.zaphyra.eu/airpodsctl/helpers" "git.zaphyra.eu/airpodsctl/types" ) func init() { c := make(chan os.Signal) signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { <-c fmt.Fprint(os.Stdout, "\033[?25h") os.Exit(0) }() } func main() { state, errStateInit := InitState() if errStateInit != nil { fmt.Fprintln(os.Stderr, "Failed to init state:", errStateInit) os.Exit(1) } defer state.Close() flag.Usage = func() { command := "" commandHelp := commandHelpStr if len(flag.Args()) > 1 { command = flag.Arg(0) commandHelp = "" } fmt.Fprintf(os.Stderr, usageStr, "0.0.0", "2025-08-11", command, commandHelp) flag.PrintDefaults() } flag.StringVar(&state.SelectedDevice, "device", "", "`` of the device that should be used (default: first device found)") flag.BoolVar(&state.SendNotifications, "notify", false, "Enable notifications") flag.BoolVar(&state.DebugOutput, "debug", false, "Enable debug-output") flag.Var(&state.OutputFormat, "format", "`` to use for output (default: cli)\nSupported formats: {cli|waybar}") flag.BoolFunc("help", "Print this help message", func(str string) error { flag.Usage() os.Exit(0) return nil }) flag.Parse() commandArgs := flag.NewFlagSet("", flag.ExitOnError) commandArgs.Usage = func() { flag.Usage() fmt.Fprint(os.Stderr, "\nCOMMAND OPTIONS\n") commandArgs.PrintDefaults() fmt.Fprint(os.Stderr, "\n") } if len(flag.Args()) < 1 { fmt.Fprintln(os.Stdout, "No command supplied!\n\nUse --help for a list of available commands.") os.Exit(0) } switch flag.Arg(0) { case "listDevices": state.listDevicesCommand() case "dumpDeviceState": state.checkSelectedDevice() state.dumpDeviceStateCommand() case "toggleAncMode": var ancMode types.ANCMode commandArgs.Var(&ancMode, "mode", "`` that should be set\nValid modes: {on|adaptive|transparency|off}") commandArgs.Parse(flag.Args()[1:]) state.checkSelectedDevice() state.toggleAncModeCommand(ancMode) case "toggleFeature": var feature string var value types.Bool commandArgs.Var(&value, "value", "`` that should be set\nValid values: {on|enable|off|disable}") commandArgs.Func("feature", "`` that should be modified\n"+featuresHelpStr, func(str string) (err error) { switch str { case "": err = errors.New("No feature supplied!\n") case "OneBudAnc": feature = "OneBudANCMode" case "VolumeSwipe": feature = "VolumeSwipeConfig" case "AdaptiveVolume": feature = "AdaptiveVolumeConfig" case "ConversationalAwareness": feature = "ConversationDetectConfig" case "AllowANCOff": feature = "AllowANCOffConfig" default: err = fmt.Errorf("Unknown Feature: %s\n", str) } return }) commandArgs.Parse(flag.Args()[1:]) state.checkSelectedDevice() state.toggleFeatureCommand(feature, value) case "monitor": state.checkSelectedDevice() state.monitorCommand() default: fmt.Fprintf(os.Stdout, helpers.BoldText("Unknown command: %s")+"\n%s\n", flag.Arg(0), commandHelpStr) } } func (state *State) checkSelectedDevice() { if state.SelectedDevice == "" { firstConnectedDevice := slices.IndexFunc(state.Devices, func(device types.Device) bool { return bool(device.Connected) }) if firstConnectedDevice != -1 { state.SelectedDevice = state.Devices[firstConnectedDevice].Address } else { fmt.Fprintln(os.Stderr, "Error: No device connected!") os.Exit(1) } } }