// BreakPilot Compliance SDK - Compliance Engine
//
// UCCA (Unified Compliance Control Assessment) Engine
// Evaluates compliance state against 45+ policy rules

package main

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

	"github.com/breakpilot/compliance-sdk/services/compliance-engine/internal/api"
	"github.com/breakpilot/compliance-sdk/services/compliance-engine/internal/ucca"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

func main() {
	logger, _ := zap.NewProduction()
	defer logger.Sync()

	// Load UCCA policies
	engine, err := ucca.NewEngine("policies")
	if err != nil {
		logger.Fatal("Failed to load UCCA policies", zap.Error(err))
	}
	logger.Info("UCCA Engine initialized", zap.Int("rules", engine.RuleCount()))

	// Set Gin mode
	if os.Getenv("ENVIRONMENT") == "production" {
		gin.SetMode(gin.ReleaseMode)
	}

	router := gin.New()
	router.Use(gin.Recovery())

	// Health check
	router.GET("/health", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"status":  "healthy",
			"service": "compliance-engine",
			"rules":   engine.RuleCount(),
		})
	})

	// API routes
	v1 := router.Group("/api/v1")
	{
		// Assessment
		v1.POST("/assess", api.Assess(engine))
		v1.POST("/assess/control", api.AssessControl(engine))
		v1.POST("/assess/regulation", api.AssessRegulation(engine))

		// Score calculation
		v1.POST("/score", api.CalculateScore(engine))
		v1.POST("/score/breakdown", api.ScoreBreakdown(engine))

		// Obligations
		v1.GET("/obligations", api.GetObligations(engine))
		v1.GET("/obligations/:regulation", api.GetObligationsByRegulation(engine))

		// Controls catalog
		v1.GET("/controls", api.GetControlsCatalog(engine))
		v1.GET("/controls/:domain", api.GetControlsByDomain(engine))

		// Policies
		v1.GET("/policies", api.ListPolicies(engine))
		v1.GET("/policies/:id", api.GetPolicy(engine))
	}

	port := os.Getenv("PORT")
	if port == "" {
		port = "8081"
	}

	srv := &http.Server{
		Addr:         ":" + port,
		Handler:      router,
		ReadTimeout:  15 * time.Second,
		WriteTimeout: 15 * time.Second,
	}

	go func() {
		logger.Info("Starting Compliance Engine", zap.String("port", port))
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			logger.Fatal("Failed to start server", zap.Error(err))
		}
	}()

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

	logger.Info("Shutting down...")
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()
	srv.Shutdown(ctx)
}
