package leaf

import (
	"flag"
	"io"
	"os"
	"sync/atomic"
)

const EnvLeafMode = "LEAF_MODE"

const (
	// DebugMode indicates gin mode is debug.
	DebugMode = "debug"
	// ReleaseMode indicates gin mode is release.
	ReleaseMode = "release"
	// TestMode indicates gin mode is test.
	TestMode = "test"
)

const (
	debugCode = iota
	releaseCode
	testCode
)

var DefaultWriter io.Writer = os.Stdout

var DefaultErrorWriter io.Writer = os.Stderr

var leafMode int32 = debugCode
var modeName atomic.Value

func init() {
	mode := os.Getenv(EnvLeafMode)
	SetMode(mode)
}

// SetMode sets gin mode according to input string.
func SetMode(value string) {
	if value == "" {
		if flag.Lookup("test.v") != nil {
			value = TestMode
		} else {
			value = DebugMode
		}
	}

	switch value {
	case DebugMode, "":
		atomic.StoreInt32(&leafMode, debugCode)
	case ReleaseMode:
		atomic.StoreInt32(&leafMode, releaseCode)
	case TestMode:
		atomic.StoreInt32(&leafMode, testCode)
	default:
		panic("leaf mode unknown: " + value + " (available mode: debug release test)")
	}
	modeName.Store(value)
}

func IsDebugging() bool {
	return atomic.LoadInt32(&leafMode) == debugCode
}

// Mode returns current gin mode.
func Mode() string {
	return modeName.Load().(string)
}
