package shellclient

import (
	"context"

	"tailscale.com/client/local"
	"tailscale.com/cmd/mirage/internal/config"
)

const defaultControllerInput = config.DefaultControllerInput

type StartupController interface {
	Enabled() (bool, error)
	SetEnabled(bool) error
}

type Client struct {
	Local      local.Client
	ConfigPath string
	Startup    StartupController
}

func (c *Client) CurrentControllerInput() (controllerInput string, hasStore bool, err error) {
	state, err := config.Load(c.ConfigPath)
	if err != nil {
		return "", false, err
	}
	if state.ControllerInput == "" {
		return defaultControllerInput, false, nil
	}
	return config.NormalizeControllerInput(state.ControllerInput), true, nil
}

func (c *Client) SaveControllerInput(controllerInput string) error {
	state, err := config.Load(c.ConfigPath)
	if err != nil {
		return err
	}
	state.ControllerInput = config.NormalizeControllerInput(controllerInput)
	return config.Save(c.ConfigPath, state)
}

func (c *Client) ResetControllerInput() error {
	state, err := config.Load(c.ConfigPath)
	if err != nil {
		return err
	}
	state.ControllerInput = ""
	return config.Save(c.ConfigPath, state)
}

func (c *Client) ControlURL() (string, error) {
	controllerInput, _, err := c.CurrentControllerInput()
	if err != nil {
		return "", err
	}
	return config.ControlURLForControllerInput(controllerInput), nil
}

func (c *Client) AuthKey() (string, error) {
	state, err := config.Load(c.ConfigPath)
	if err != nil {
		return "", err
	}
	return state.AuthKey, nil
}

func (c *Client) SetAuthKey(authKey string) error {
	state, err := config.Load(c.ConfigPath)
	if err != nil {
		return err
	}
	state.AuthKey = authKey
	return config.Save(c.ConfigPath, state)
}

func (c *Client) GetAutoStartUp(_ context.Context) (bool, error) {
	if c.Startup == nil {
		return false, nil
	}
	return c.Startup.Enabled()
}

func (c *Client) SetAutoStartUp(_ context.Context) error {
	if c.Startup == nil {
		return nil
	}
	enabled, err := c.Startup.Enabled()
	if err != nil {
		return err
	}
	return c.Startup.SetEnabled(!enabled)
}
