package app

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"go.uber.org/zap"

	"github.com/tidbcloud/inference-service/internal/config"
	"github.com/tidbcloud/inference-service/internal/version"
)

var (
	cfgFile string

	rootCmd = &cobra.Command{
		Use:               "inference-service",
		Short:             "Inference service",
		CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true},
	}

	serveCmd = &cobra.Command{
		Use:   "serve",
		Short: "Start the HTTP server",
		Long:  "Start the HTTP server to handle embedding requests",
		Run: func(cmd *cobra.Command, args []string) {
			server := NewServer()
			if err := server.Setup(); err != nil {
				zap.L().Fatal("Failed to setup server", zap.Error(err))
			}
			if err := server.ServeHTTP(); err != nil {
				zap.L().Fatal("Failed to start server", zap.Error(err))
			}
		},
	}

	versionCmd = &cobra.Command{
		Use:   "version",
		Short: "Print version information",
		Long:  "Print version information including build details",
		Run: func(cmd *cobra.Command, args []string) {
			info := version.GetBuildInfo()
			fmt.Printf("Version:    %s\n", info.Version)
			fmt.Printf("Git Commit: %s\n", info.GitCommit)
			fmt.Printf("Git Branch: %s\n", info.GitBranch)
			fmt.Printf("Build Time: %s\n", info.BuildTime)
			fmt.Printf("Go Version: %s\n", info.GoVersion)
		},
	}
)

func initConfig() {
	if err := config.LoadConfig(cfgFile); err != nil {
		zap.L().Fatal("Failed to load config", zap.Error(err))
	}
}

func initDefaultLogger() {
	c := zap.NewProductionConfig()
	c.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
	logger, _ := c.Build()
	zap.ReplaceGlobals(logger)
}

func initLogger() {
	c := zap.NewProductionConfig()
	c.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
	if config.Global().Server.LogLevel != "" {
		var err error
		c.Level, err = zap.ParseAtomicLevel(config.Global().Server.LogLevel)
		if err != nil {
			zap.L().Fatal("Invalid log level",
				zap.String("logLevel", config.Global().Server.LogLevel),
				zap.Error(err))
		}
	}
	logger, err := c.Build()
	if err != nil {
		zap.L().Fatal("Failed to build logger", zap.Error(err))
	}
	zap.ReplaceGlobals(logger)
}

func init() {
	initDefaultLogger() // Initialize logger using default

	cobra.OnInitialize(initConfig)
	cobra.OnInitialize(initLogger)

	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./config.yaml)")
	rootCmd.AddCommand(serveCmd)
	rootCmd.AddCommand(versionCmd)
}

// Execute runs the root command
func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}
