// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package color provides functions for printing in different colors.
package color

import (
	"fmt"
	"os"

	"go.fuchsia.dev/tools/isatty"
)

// Colorfn is a function type that takes a formatted string and returns it in a certain color.
type Colorfn func(format string, a ...interface{}) string

const (
	escape = "\033["
	clear  = escape + "0m"
)

// ColorCode represents the int used for coloring formatted strings in a certain color.
type ColorCode int

// Foreground text colors
const (
	BlackFg ColorCode = iota + 30
	RedFg
	GreenFg
	YellowFg
	BlueFg
	MagentaFg
	CyanFg
	WhiteFg
	DefaultFg
)

// Color provides an interface for a color or monochrome type that will be returned by NewColor()
// based on whether coloring is enabled or not.
type Color interface {
	Black(format string, a ...interface{}) string
	Red(format string, a ...interface{}) string
	Green(format string, a ...interface{}) string
	Yellow(format string, a ...interface{}) string
	Blue(format string, a ...interface{}) string
	Magenta(format string, a ...interface{}) string
	Cyan(format string, a ...interface{}) string
	White(format string, a ...interface{}) string
	DefaultColor(format string, a ...interface{}) string
	WithColor(code ColorCode, format string, a ...interface{}) string
	Enabled() bool
}

type color struct{}

func (color) Black(format string, a ...interface{}) string { return colorString(BlackFg, format, a...) }
func (color) Red(format string, a ...interface{}) string   { return colorString(RedFg, format, a...) }
func (color) Green(format string, a ...interface{}) string { return colorString(GreenFg, format, a...) }
func (color) Yellow(format string, a ...interface{}) string {
	return colorString(YellowFg, format, a...)
}
func (color) Blue(format string, a ...interface{}) string { return colorString(BlueFg, format, a...) }
func (color) Magenta(format string, a ...interface{}) string {
	return colorString(MagentaFg, format, a...)
}
func (color) Cyan(format string, a ...interface{}) string  { return colorString(CyanFg, format, a...) }
func (color) White(format string, a ...interface{}) string { return colorString(WhiteFg, format, a...) }
func (color) DefaultColor(format string, a ...interface{}) string {
	return colorString(DefaultFg, format, a...)
}
func (color) WithColor(code ColorCode, format string, a ...interface{}) string {
	return colorString(code, format, a...)
}
func (color) Enabled() bool {
	return true
}

func colorString(c ColorCode, format string, a ...interface{}) string {
	if c == DefaultFg {
		return fmt.Sprintf(format, a...)
	}
	return fmt.Sprintf("%v%vm%v%v", escape, c, fmt.Sprintf(format, a...), clear)
}

type monochrome struct{}

func (monochrome) Black(format string, a ...interface{}) string   { return fmt.Sprintf(format, a...) }
func (monochrome) Red(format string, a ...interface{}) string     { return fmt.Sprintf(format, a...) }
func (monochrome) Green(format string, a ...interface{}) string   { return fmt.Sprintf(format, a...) }
func (monochrome) Yellow(format string, a ...interface{}) string  { return fmt.Sprintf(format, a...) }
func (monochrome) Blue(format string, a ...interface{}) string    { return fmt.Sprintf(format, a...) }
func (monochrome) Magenta(format string, a ...interface{}) string { return fmt.Sprintf(format, a...) }
func (monochrome) Cyan(format string, a ...interface{}) string    { return fmt.Sprintf(format, a...) }
func (monochrome) White(format string, a ...interface{}) string   { return fmt.Sprintf(format, a...) }
func (monochrome) DefaultColor(format string, a ...interface{}) string {
	return fmt.Sprintf(format, a...)
}
func (monochrome) WithColor(_ ColorCode, format string, a ...interface{}) string {
	return fmt.Sprintf(format, a...)
}
func (monochrome) Enabled() bool {
	return false
}

// EnableColor represents whether or not to return colored strings.
type EnableColor int

const (
	ColorNever EnableColor = iota
	ColorAuto
	ColorAlways
)

func isColorAvailable() bool {
	term := os.Getenv("TERM")
	switch term {
	case "dumb", "":
		return false
	}
	return isatty.IsTerminal()
}

// NewColor returns a color or monochrome type depending on the value of enableColor.
// A monochrome type will always return the string in the default color.
func NewColor(enableColor EnableColor) Color {
	ec := enableColor != ColorNever
	if enableColor == ColorAuto {
		ec = isColorAvailable()
	}
	if ec {
		return color{}
	} else {
		return monochrome{}
	}
}

// String returns the string value of the EnableColor type.
func (ec *EnableColor) String() string {
	switch *ec {
	case ColorNever:
		return "never"
	case ColorAuto:
		return "auto"
	case ColorAlways:
		return "always"
	}
	return ""
}

// Set sets the EnableColor type based on the string value.
func (ec *EnableColor) Set(s string) error {
	switch s {
	case "never":
		*ec = ColorNever
	case "auto":
		*ec = ColorAuto
	case "always":
		*ec = ColorAlways
	default:
		return fmt.Errorf("%s is not a valid color value", s)
	}
	return nil
}
