// BreakPilot Compliance SDK - Security Scanner Service
//
// Orchestrates security scanning tools and aggregates results.

package main

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

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

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

	// Initialize scanner manager
	scannerManager := scanner.NewManager(logger)

	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": "security-scanner",
			"tools":   scannerManager.AvailableTools(),
		})
	})

	// API routes
	v1 := router.Group("/api/v1")
	{
		// Scanning
		v1.POST("/scan", api.StartScan(scannerManager))
		v1.GET("/scan/:scanId", api.GetScanStatus(scannerManager))
		v1.GET("/scan/:scanId/results", api.GetScanResults(scannerManager))

		// Findings
		v1.GET("/findings", api.GetFindings(scannerManager))
		v1.GET("/findings/:findingId", api.GetFinding(scannerManager))
		v1.PUT("/findings/:findingId/status", api.UpdateFindingStatus(scannerManager))

		// SBOM
		v1.POST("/sbom/generate", api.GenerateSBOM(scannerManager))
		v1.GET("/sbom/:sbomId", api.GetSBOM(scannerManager))
		v1.GET("/sbom/:sbomId/export/:format", api.ExportSBOM(scannerManager))

		// Recommendations
		v1.GET("/recommendations", api.GetRecommendations(scannerManager))

		// Tool status
		v1.GET("/tools", api.GetToolsStatus(scannerManager))
	}

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

	srv := &http.Server{
		Addr:         ":" + port,
		Handler:      router,
		ReadTimeout:  15 * time.Second,
		WriteTimeout: 300 * time.Second, // Long timeout for scans
	}

	go func() {
		logger.Info("Starting Security Scanner", 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)
}
