package auth

import (
	"flag"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/jfraeys/fetch_ml/internal/fileutil"
)

// Flags holds authentication-related command line flags
type Flags struct {
	APIKey     string
	APIKeyFile string
	ConfigFile string
	EnableAuth bool
	ShowHelp   bool
}

// ParseAuthFlags parses authentication command line flags
func ParseAuthFlags() *Flags {
	flags := &Flags{}

	flag.StringVar(&flags.APIKey, "api-key", "", "API key for authentication")
	flag.StringVar(&flags.APIKeyFile, "api-key-file", "", "Path to file containing API key")
	flag.StringVar(&flags.ConfigFile, "config", "", "Configuration file path")
	flag.BoolVar(&flags.EnableAuth, "enable-auth", false, "Enable authentication")
	flag.BoolVar(&flags.ShowHelp, "auth-help", false, "Show authentication help")

	// Custom help flag that doesn't exit
	flag.Usage = func() {}

	flag.Parse()

	return flags
}

// GetAPIKeyFromSources gets API key from multiple sources in priority order
func GetAPIKeyFromSources(flags *Flags) string {
	// 1. Command line flag (highest priority)
	if flags.APIKey != "" {
		// Warn about process list exposure
		log.Println("WARNING: --api-key exposes credential in process list. Use --api-key-file for better security.")
		return flags.APIKey
	}

	// 2. Explicit file flag
	if flags.APIKeyFile != "" {
		contents, readErr := os.ReadFile(flags.APIKeyFile)
		if readErr == nil {
			return strings.TrimSpace(string(contents))
		}
		log.Printf("Warning: Could not read API key file %s: %v", flags.APIKeyFile, readErr)
	}

	// 3. Environment variable
	if envKey := os.Getenv("FETCH_ML_API_KEY"); envKey != "" {
		return envKey
	}

	// 4. File-based key (for automated scripts)
	if fileKey := os.Getenv("FETCH_ML_API_KEY_FILE"); fileKey != "" {
		content, err := fileutil.SecureFileRead(fileKey)
		if err == nil {
			return strings.TrimSpace(string(content))
		}
		log.Printf("Warning: Could not read API key file %s: %v", fileKey, err)
	}

	return ""
}

// ValidateFlags validates parsed authentication flags
func ValidateFlags(flags *Flags) error {
	if flags.ShowHelp {
		PrintAuthHelp()
		os.Exit(0)
	}

	if flags.APIKeyFile != "" {
		if _, err := os.Stat(flags.APIKeyFile); err != nil {
			return fmt.Errorf("api key file not found: %s", flags.APIKeyFile)
		}
		if err := CheckConfigFilePermissions(flags.APIKeyFile); err != nil {
			log.Printf("Warning: %v", err)
		}
	}

	// If config file is specified, check if it exists
	if flags.ConfigFile != "" {
		if _, err := os.Stat(flags.ConfigFile); err != nil {
			return fmt.Errorf("config file not found: %s", flags.ConfigFile)
		}

		// Check file permissions
		if err := CheckConfigFilePermissions(flags.ConfigFile); err != nil {
			log.Printf("Warning: %v", err)
		}
	}

	return nil
}

// PrintAuthHelp prints authentication-specific help
func PrintAuthHelp() {
	fmt.Println("Authentication Options:")
	fmt.Println("  --api-key <key>        API key for authentication")
	fmt.Println("  --api-key-file <path>  Read API key from file")
	fmt.Println("  --config <file>         Configuration file path")
	fmt.Println("  --enable-auth           Enable authentication (if disabled)")
	fmt.Println("  --auth-help             Show this help")
	fmt.Println()
	fmt.Println("Environment Variables:")
	fmt.Println("  FETCH_ML_API_KEY         API key for authentication")
	fmt.Println("  FETCH_ML_API_KEY_FILE    File containing API key")
	fmt.Println("  FETCH_ML_ENV            Environment (development/production)")
	fmt.Println("  FETCH_ML_ALLOW_INSECURE_AUTH  Allow insecure auth (dev only)")
	fmt.Println()
	fmt.Println("Security Notes:")
	fmt.Println("  - API keys in command line may be visible in process lists")
	fmt.Println("  - Environment variables are preferred for automated scripts")
	fmt.Println("  - File-based keys should have restricted permissions (600)")
	fmt.Println("  - Authentication is mandatory in production environments")
}
