package main

import (
	"fmt"

	"github.com/charlie0129/batt/pkg/config"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

func NewSetPreventIdleSleepCommand() *cobra.Command {
	return newEnableDisableCommand(
		"prevent-idle-sleep",
		"Set whether to prevent idle sleep during a charging session",
		`Set whether to prevent idle sleep during a charging session.

Due to macOS limitations, batt will be paused when your computer goes to sleep. As a result, when you are in a charging session and your computer goes to sleep, there is no way for batt to stop charging (since batt is paused by macOS) and the battery will charge to 100%. This option, together with disable-charging-pre-sleep, will prevent this from happening.

This option tells macOS NOT to go to sleep when the computer is in a charging session, so batt can continue to work until charging is finished. Note that it will only prevent **idle** sleep, when 1) charging is active 2) battery charge limit is enabled. So your computer can go to sleep as soon as a charging session is completed.

However, this options does not prevent manual sleep (limitation of macOS). For example, if you manually put your computer to sleep (by choosing the Sleep option in the top-left Apple menu) or close the lid, batt will still be paused and the issue mentioned above will still happen. This is where disable-charging-pre-sleep comes in.`,
		func() (string, error) { return apiClient.SetPreventIdleSleep(true) },
		func() (string, error) { return apiClient.SetPreventIdleSleep(false) },
	)
}

func NewSetDisableChargingPreSleepCommand() *cobra.Command {
	return newEnableDisableCommand(
		"disable-charging-pre-sleep",
		"Set whether to disable charging before sleep if charge limit is enabled",
		`Set whether to disable charging before sleep if charge limit is enabled.

As described in preventing-idle-sleep, batt will be paused by macOS when your computer goes to sleep, and there is no way for batt to continue controlling battery charging. This option will disable charging just before sleep, so your computer will not overcharge during sleep, even if the battery charge is below the limit.`,
		func() (string, error) { return apiClient.SetDisableChargingPreSleep(true) },
		func() (string, error) { return apiClient.SetDisableChargingPreSleep(false) },
	)
}

func NewSetPreventSystemSleepCommand() *cobra.Command {
	return newEnableDisableCommand(
		"prevent-system-sleep",
		"Set whether to prevent system sleep during a charging session (experimental)",
		`This option tells macOS to create power assertion, which prevents sleep, when all conditions are met:

1) charging is active
2) battery charge limit is enabled
3) computer is connected to charger.
So your computer can go to sleep as soon as a charging session is completed / charger disconnected.

Does similar thing to prevent-idle-sleep, but works for manual sleep too.

Note: please disable disable-charging-pre-sleep and prevent-idle-sleep, while this feature is in use`,
		func() (string, error) { return apiClient.SetPreventSystemSleep(true) },
		func() (string, error) { return apiClient.SetPreventSystemSleep(false) },
	)
}

func NewSetControlMagSafeLEDCommand() *cobra.Command {
	use := "magsafe-led"
	cmd := &cobra.Command{
		Use:     use,
		GroupID: gAdvanced,
		Short:   "Control MagSafe LED according to battery charging status",
	}

	enable := &cobra.Command{
		Use: "enable",
		Short: `Enable MagSafe LED control. The LED will reflect charging status:
		- Green: Charge limit is reached and charging is stopped.
		- Orange: Charging is in progress.
		- Off: Woke from sleep, charging is off and batt is awaiting control.`,
		RunE: func(_ *cobra.Command, _ []string) error {
			ret, err := apiClient.SetControlMagSafeLED(config.ControlMagSafeModeEnabled)
			if err != nil {
				return fmt.Errorf("failed to set to %s: %v", use, err)
			}
			if ret != "" {
				logrus.Infof("daemon responded: %s", ret)
			}
			logrus.Infof("successfully set to %s", use)
			return nil
		},
	}

	disable := &cobra.Command{
		Use:   "disable",
		Short: "Disable MagSafe LED control.",
		RunE: func(_ *cobra.Command, _ []string) error {
			ret, err := apiClient.SetControlMagSafeLED(config.ControlMagSafeModeDisabled)
			if err != nil {
				return fmt.Errorf("failed to set to %s: %v", use, err)
			}
			if ret != "" {
				logrus.Infof("daemon responded: %s", ret)
			}
			logrus.Infof("successfully set to %s", use)
			return nil
		},
	}

	alwaysOff := &cobra.Command{
		Use:   "always-off",
		Short: "Force the MagSafe LED to stay off.",
		RunE: func(_ *cobra.Command, _ []string) error {
			ret, err := apiClient.SetControlMagSafeLED(config.ControlMagSafeModeAlwaysOff)
			if err != nil {
				return fmt.Errorf("failed to set to %s: %v", use, err)
			}
			if ret != "" {
				logrus.Infof("daemon responded: %s", ret)
			}
			logrus.Infof("successfully set to %s", use)
			return nil
		},
	}

	cmd.AddCommand(enable, disable, alwaysOff)
	return cmd
}
