package cmd

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var cfgFile string

// rootCmd is the base command when called without any subcommands.
var rootCmd = &cobra.Command{
	Use:   "keyhunter",
	Short: "KeyHunter -- detect leaked LLM API keys across 108+ providers",
	Long: `KeyHunter scans files, git history, and internet sources for leaked LLM API keys.
Supports 108+ providers with Aho-Corasick pre-filtering and regex + entropy detection.`,
	SilenceUsage: true,
}

// Execute is the entry point called by main.go.
//
// OUT-06 exit-code contract:
//   - 0: clean scan (no findings)
//   - 1: findings present (emitted directly by scanCmd via os.Exit(1))
//   - 2: scan/tool error (any RunE returning a non-nil error)
//
// Cobra prints the error message itself; we only translate the non-nil return
// into exit code 2 so CI consumers can distinguish "found leaks" from "scan
// failed".
func Execute() {
	if err := rootCmd.Execute(); err != nil {
		os.Exit(2)
	}
}

func init() {
	cobra.OnInitialize(initConfig)
	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default: ~/.keyhunter.yaml)")
	rootCmd.AddCommand(scanCmd)
	rootCmd.AddCommand(providersCmd)
	rootCmd.AddCommand(configCmd)
	rootCmd.AddCommand(legalCmd)
	// Stub commands for future phases (per CLI-01 requirement of 11 commands)
	rootCmd.AddCommand(verifyCmd)
	rootCmd.AddCommand(importCmd)
	rootCmd.AddCommand(reconCmd)
	rootCmd.AddCommand(keysCmd)
	rootCmd.AddCommand(serveCmd)
	rootCmd.AddCommand(dorksCmd)
	rootCmd.AddCommand(hookCmd)
	rootCmd.AddCommand(scheduleCmd)
}

func initConfig() {
	if cfgFile != "" {
		viper.SetConfigFile(cfgFile)
	} else {
		home, err := os.UserHomeDir()
		if err != nil {
			fmt.Fprintln(os.Stderr, "warning: cannot determine home directory:", err)
			return
		}
		viper.SetConfigName(".keyhunter")
		viper.SetConfigType("yaml")
		viper.AddConfigPath(home)
		viper.AddConfigPath(".")
	}

	viper.SetEnvPrefix("KEYHUNTER")
	viper.AutomaticEnv()

	// Defaults
	viper.SetDefault("scan.workers", 0) // 0 = auto (CPU*8)
	viper.SetDefault("database.path", filepath.Join(mustHomeDir(), ".keyhunter", "keyhunter.db"))

	// Config file is optional -- ignore if not found
	_ = viper.ReadInConfig()
}

func mustHomeDir() string {
	h, _ := os.UserHomeDir()
	return h
}
