package iostreams

import "fmt"

// ColorScheme provides semantic color methods that respect whether color output is enabled.
type ColorScheme struct {
	enabled bool
}

// NewColorScheme creates a ColorScheme. When enabled is false, all methods return
// undecorated text.
func NewColorScheme(enabled bool) *ColorScheme {
	return &ColorScheme{enabled: enabled}
}

// colorize wraps text in ANSI escape codes if color is enabled.
func (cs *ColorScheme) colorize(code string, text string) string {
	if !cs.enabled {
		return text
	}
	return fmt.Sprintf("\033[%sm%s\033[0m", code, text)
}

// Bold renders text in bold.
func (cs *ColorScheme) Bold(s string) string {
	return cs.colorize("1", s)
}

// Red renders text in red.
func (cs *ColorScheme) Red(s string) string {
	return cs.colorize("31", s)
}

// Green renders text in green.
func (cs *ColorScheme) Green(s string) string {
	return cs.colorize("32", s)
}

// Yellow renders text in yellow.
func (cs *ColorScheme) Yellow(s string) string {
	return cs.colorize("33", s)
}

// Cyan renders text in cyan.
func (cs *ColorScheme) Cyan(s string) string {
	return cs.colorize("36", s)
}

// Magenta renders text in magenta.
func (cs *ColorScheme) Magenta(s string) string {
	return cs.colorize("35", s)
}

// Muted renders text in gray (dimmed).
func (cs *ColorScheme) Muted(s string) string {
	return cs.colorize("90", s)
}

// SuccessIcon returns a green check mark if color is enabled, plain otherwise.
func (cs *ColorScheme) SuccessIcon() string {
	return cs.Green("✓")
}

// WarningIcon returns a yellow exclamation mark if color is enabled, plain otherwise.
func (cs *ColorScheme) WarningIcon() string {
	return cs.Yellow("!")
}

// FailureIcon returns a red X mark if color is enabled, plain otherwise.
func (cs *ColorScheme) FailureIcon() string {
	return cs.Red("✗")
}

// SuccessIconWithColor returns the success icon followed by the message in green.
func (cs *ColorScheme) SuccessIconWithColor(msg string) string {
	return cs.SuccessIcon() + " " + cs.Green(msg)
}
