package cli

import (
	"io"
	"os"

	"github.com/spf13/afero"
)

// NO_COLOR disables colored output when set. Automatically true if the
// NO_COLOR environment variable is present (per https://no-color.org/).
var NO_COLOR bool

func init() {
	NO_COLOR = false
	if _, exists := os.LookupEnv("NO_COLOR"); exists {
		NO_COLOR = true
	}
}

// RunOptions contains all configuration for running the CLI application.
// Use DefaultRunOptions for standard CLI execution, or construct manually for testing.
type RunOptions struct {
	Appname string    // Application name displayed in help and version output
	Version string    // Version string (typically set at build time)
	Gitrev  string    // Git revision hash (typically set at build time)
	Args    []string  // Command-line arguments (typically os.Args)
	Stdin   io.Reader // Standard input stream
	Stdout  io.Writer // Standard output stream
	Stderr  io.Writer // Standard error stream
	Fs      afero.Fs  // Filesystem abstraction for file operations
}

// DefaultRunOptions returns RunOptions configured for normal CLI execution.
func DefaultRunOptions(appname, version, gitrev string) *RunOptions {
	return &RunOptions{
		Appname: appname,
		Version: version,
		Gitrev:  gitrev,
		Args:    os.Args,
		Stdin:   os.Stdin,
		Stdout:  os.Stdout,
		Stderr:  os.Stderr,
		Fs:      afero.NewOsFs(),
	}
}

// Run creates and runs the CLI application with default options.
func Run(appname, version, gitrev string) int {
	return RunWithOptions(DefaultRunOptions(appname, version, gitrev))
}

// RunWithOptions creates and runs the CLI application with the given options.
func RunWithOptions(opts *RunOptions) int {
	m := &CLIApp{
		appname:  opts.Appname,
		version:  opts.Version,
		gitrev:   opts.Gitrev,
		exitCode: 0,
		Stdin:    opts.Stdin,
		Stdout:   opts.Stdout,
		Stderr:   opts.Stderr,
		Fs:       opts.Fs,
	}

	m.run(opts.Args)
	return m.exitCode
}
