package startup

import (
	"errors"
)

const AppName = "Mirage"

var ErrValueNotFound = errors.New("startup value not found")

type ValueStore interface {
	GetString(name string) (string, error)
	SetString(name, value string) error
	Delete(name string) error
}

type Controller struct {
	Store          ValueStore
	ExecutablePath func() (string, error)
}

func (c *Controller) Enabled() (bool, error) {
	if c.Store == nil {
		return false, errors.New("startup store is nil")
	}
	_, err := c.Store.GetString(AppName)
	switch {
	case err == nil:
		return true, nil
	case errors.Is(err, ErrValueNotFound):
		return false, nil
	default:
		return false, err
	}
}

func (c *Controller) SetEnabled(enabled bool) error {
	if c.Store == nil {
		return errors.New("startup store is nil")
	}
	if !enabled {
		err := c.Store.Delete(AppName)
		if errors.Is(err, ErrValueNotFound) {
			return nil
		}
		return err
	}
	if c.ExecutablePath == nil {
		return errors.New("executable path callback is nil")
	}
	exePath, err := c.ExecutablePath()
	if err != nil {
		return err
	}
	return c.Store.SetString(AppName, `"`+exePath+`"`)
}

func (c *Controller) RepairEnabledPath() error {
	if c.Store == nil {
		return errors.New("startup store is nil")
	}
	current, err := c.Store.GetString(AppName)
	if errors.Is(err, ErrValueNotFound) {
		return nil
	}
	if err != nil {
		return err
	}
	if c.ExecutablePath == nil {
		return errors.New("executable path callback is nil")
	}
	exePath, err := c.ExecutablePath()
	if err != nil {
		return err
	}
	want := `"` + exePath + `"`
	if current == want {
		return nil
	}
	return c.Store.SetString(AppName, want)
}
