// Package main provides the claudebox-sidecar HTTP server.
// This sidecar runs alongside Claude Code in worker pods, exposing HTTP endpoints
// for execute, git, and SDLC operations - replacing kubectl exec calls.
package main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
	"github.com/orchard9/rdev/internal/claudebox"
	"github.com/orchard9/rdev/internal/envutil"
	"github.com/orchard9/rdev/internal/logging"
)

func main() {
	// Configure logging
	logLevel := logging.LevelInfo
	if envutil.GetEnvBool("DEBUG", false) {
		logLevel = logging.LevelDebug
	}
	log := logging.New(logging.Config{
		Level:  logLevel,
		Format: logging.FormatJSON,
	})

	// Configuration from environment
	port := envutil.GetEnv("PORT", "8080")
	workDir := envutil.GetEnv("WORKSPACE_DIR", "/workspace")
	giteaToken := os.Getenv("GITEA_TOKEN") // Required for git push auth
	gitUser := envutil.GetEnv("GIT_USER", "rdev-worker")
	gitEmail := envutil.GetEnv("GIT_EMAIL", "worker@threesix.ai")

	// Create server components
	executor := claudebox.NewExecutor(workDir)
	gitOps := claudebox.NewGitOperations(claudebox.GitOperationsConfig{
		WorkDir:    workDir,
		GiteaToken: giteaToken,
		GitUser:    gitUser,
		GitEmail:   gitEmail,
		Logger:     log.Slog(),
	})
	sdlcRunner := claudebox.NewSDLCRunner(claudebox.SDLCRunnerConfig{
		WorkDir: workDir,
		Logger:  log.Slog(),
	})

	// Create the server
	server := claudebox.NewServer(claudebox.ServerConfig{
		Executor:   executor,
		GitOps:     gitOps,
		SDLCRunner: sdlcRunner,
		Logger:     log.Slog(),
	})

	// Create router
	r := chi.NewRouter()
	r.Use(middleware.RequestID)
	r.Use(middleware.RealIP)
	r.Use(logging.Middleware(logging.MiddlewareConfig{
		Logger: log,
	}))
	r.Use(middleware.Recoverer)
	r.Use(middleware.Timeout(10 * time.Minute))

	// Mount server routes
	server.Mount(r)

	// Create HTTP server
	addr := fmt.Sprintf(":%s", port)
	httpServer := &http.Server{
		Addr:         addr,
		Handler:      r,
		ReadTimeout:  30 * time.Second,
		WriteTimeout: 15 * time.Minute, // Long timeout for streaming responses
		IdleTimeout:  60 * time.Second,
	}

	// Start server in goroutine
	go func() {
		log.Info("starting claudebox-sidecar", "addr", addr, "workDir", workDir)
		if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Error("server error", logging.FieldError, err)
			os.Exit(1)
		}
	}()

	// Wait for shutdown signal
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	log.Info("shutting down server")

	// Graceful shutdown with timeout
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	if err := httpServer.Shutdown(ctx); err != nil {
		log.Error("server shutdown error", logging.FieldError, err)
		os.Exit(1)
	}

	log.Info("server stopped")
}
