package ghactions

import (
	"fmt"
	"os"

	"github.com/google/go-github/v56/github"
	"github.com/spf13/cobra"

	"github.com/stacklok/frizbee/pkg/config"
	cliutils "github.com/stacklok/frizbee/pkg/utils/cli"
)

// CmdGHActions represents the ghactions command
func CmdGHActions() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "ghactions",
		Short: "Replace tags in GitHub Actions workflows",
		Long: `This utility replaces tag or branch references in GitHub Actions workflows
with the latest commit hash of the referenced tag or branch.
	
Example:

	$ frizbee ghactions -d .github/workflows

This will replace all tag or branch references in all GitHub Actions workflows
for the given directory.
`,
		RunE:         replace,
		SilenceUsage: true,
	}

	// flags
	cmd.Flags().StringP("dir", "d", ".github/workflows", "workflows directory")

	cliutils.DeclareReplacerFlags(cmd)

	// sub-commands
	cmd.AddCommand(CmdOne())
	cmd.AddCommand(CmdList())

	return cmd
}

func replace(cmd *cobra.Command, _ []string) error {
	dir := cmd.Flag("dir").Value.String()
	dryRun, err := cmd.Flags().GetBool("dry-run")
	if err != nil {
		return fmt.Errorf("failed to get dry-run flag: %w", err)
	}
	errOnModified, err := cmd.Flags().GetBool("error")
	if err != nil {
		return fmt.Errorf("failed to get error flag: %w", err)
	}
	quiet, err := cmd.Flags().GetBool("quiet")
	if err != nil {
		return fmt.Errorf("failed to get quiet flag: %w", err)
	}
	cfg, err := config.FromContext(cmd.Context())
	if err != nil {
		return fmt.Errorf("failed to get config from context: %w", err)
	}

	dir = cliutils.ProcessDirNameForBillyFS(dir)

	ctx := cmd.Context()

	ghcli := github.NewClient(nil)

	tok := os.Getenv("GITHUB_TOKEN")
	if tok != "" {
		ghcli = ghcli.WithAuthToken(tok)
	}

	replacer := &replacer{
		Replacer: cliutils.Replacer{
			Dir:           dir,
			DryRun:        dryRun,
			Quiet:         quiet,
			ErrOnModified: errOnModified,
			Cmd:           cmd,
		},
		ghcli: ghcli,
	}

	return replacer.do(ctx, cfg)
}
