package cmd

import (
	"errors"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"syscall"

	"github.com/fatih/color"
)

func RunGrafanaCmd(subCmd string) int {
	curr, err := os.Executable()
	if err != nil {
		fmt.Println("Error locating executable:", err)
		return 1
	}

	switch filepath.Base(curr) {
	case "grafana-server":
		fmt.Printf("%s: %s\n", color.RedString("Deprecation warning"), "The standalone 'grafana-server' program is deprecated and will be removed in the future. Please update all uses of 'grafana-server' to 'grafana server'")
	case "grafana-cli":
		fmt.Printf("%s: %s\n", color.RedString("Deprecation warning"), "The standalone 'grafana-cli' program is deprecated and will be removed in the future. Please update all uses of 'grafana-cli' to 'grafana cli'")
	}

	executable := "grafana"
	if runtime.GOOS == "windows" {
		executable += ".exe"
	}

	binary := filepath.Join(filepath.Dir(filepath.Clean(curr)), executable)
	if _, err := os.Stat(binary); err != nil {
		binary, err = exec.LookPath(executable)
		if err != nil {
			fmt.Printf("Error locating %s: %s\n", executable, err)
			return 1
		}
	}

	// windows doesn't support syscall.Exec so we just run the main binary as a command
	if runtime.GOOS == "windows" {
		// bypassing gosec G204 because we need to build the command programmatically
		// nolint:gosec
		cmd := exec.Command(binary, append([]string{subCmd}, os.Args[1:]...)...)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Stdin = os.Stdin
		cmd.Env = os.Environ()
		err := cmd.Run()
		if err == nil {
			return 0
		}
		var exitError *exec.ExitError
		if errors.As(err, &exitError) {
			return exitError.ExitCode()
		}
		return 1
	}

	args := append([]string{"grafana", subCmd}, os.Args[1:]...)

	// bypassing gosec G204 because we need to build the command programmatically
	// nolint:gosec
	execErr := syscall.Exec(binary, args, os.Environ())
	if execErr != nil {
		fmt.Printf("Error running %s: %s\n", binary, execErr)
		return 1
	}

	return 0
}
