package main

import (
	"context"
	"fmt"
	"log/slog"
	"os"
	"time"

	"github.com/spf13/cobra"
	"github.com/daniel/cursor-adapter/internal/bridge"
	"github.com/daniel/cursor-adapter/internal/config"
	"github.com/daniel/cursor-adapter/internal/server"
)

var (
	configPath   string
	port         int
	debug        bool
	useACP       bool
	chatOnlySet  bool
	chatOnlyFlag bool
)

func main() {
	rootCmd := &cobra.Command{
		Use:   "cursor-adapter",
		Short: "OpenAI-compatible proxy for Cursor CLI",
		RunE:  run,
	}

	rootCmd.Flags().StringVarP(&configPath, "config", "c", "", "config file path (default: ~/.cursor-adapter/config.yaml)")
	rootCmd.Flags().IntVarP(&port, "port", "p", 0, "server port (overrides config)")
	rootCmd.Flags().BoolVar(&debug, "debug", false, "enable debug logging")
	rootCmd.Flags().BoolVar(&useACP, "use-acp", false, "use Cursor ACP transport instead of CLI stream-json")
	rootCmd.Flags().BoolVar(&chatOnlyFlag, "chat-only-workspace", true, "isolate Cursor CLI in an empty temp workspace with overridden HOME/CURSOR_CONFIG_DIR (set to false to let Cursor agent see the adapter's cwd)")
	rootCmd.PreRun = func(cmd *cobra.Command, args []string) {
		chatOnlySet = cmd.Flags().Changed("chat-only-workspace")
	}

	if err := rootCmd.Execute(); err != nil {
		os.Exit(1)
	}
}

func run(cmd *cobra.Command, args []string) error {
	var logLevel slog.Level
	if debug {
		logLevel = slog.LevelDebug
	} else {
		logLevel = slog.LevelInfo
	}
	logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: logLevel}))
	slog.SetDefault(logger)

	cfg, err := config.Load(configPath)
	if err != nil {
		return fmt.Errorf("load config: %w", err)
	}

	if port > 0 {
		cfg.Port = port
	}
	if useACP {
		cfg.UseACP = true
	}
	if chatOnlySet {
		cfg.ChatOnlyWorkspace = chatOnlyFlag
	}

	br := bridge.NewBridge(
		cfg.CursorCLIPath,
		logger,
		cfg.UseACP,
		cfg.ChatOnlyWorkspace,
		cfg.MaxConcurrent,
		time.Duration(cfg.Timeout)*time.Second,
	)

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := br.CheckHealth(ctx); err != nil {
		return fmt.Errorf("cursor cli not available: %w", err)
	}
	logger.Info("Cursor CLI OK")

	srv := server.New(cfg, br)
	mode := "CLI"
	if cfg.UseACP {
		mode = "ACP"
	}
	logger.Info("Starting cursor-adapter",
		"port", cfg.Port,
		"mode", mode,
		"chat_only_workspace", cfg.ChatOnlyWorkspace,
	)
	return srv.Run()
}
