package main import ( "context" "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" "datarush/internal/gw/config" "datarush/internal/gw/grpc_client" "datarush/internal/gw/handler" "datarush/internal/gw/middleware" "datarush/internal/gw/router" "datarush/internal/gw/storage" ) func main() { cfg, err := config.Load() if err != nil { log.Fatalf("Failed to load config: %v", err) } ctx := context.Background() clientFactory := grpc_client.NewClientFactory() defer clientFactory.Close() authClient, err := grpc_client.NewAuthClient(ctx, cfg.GRPC.AuthServiceAddr, clientFactory) if err != nil { log.Printf("Warning: Failed to create auth client: %v", err) authClient = nil } ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() userClient, err := grpc_client.NewUserClient(ctx, cfg.GRPC.UserServiceAddr, clientFactory) if err != nil { log.Printf("Warning: Failed to create user client: %v", err) userClient = nil } competitionClient, err := grpc_client.NewCompetitionClient(ctx, cfg.GRPC.CompetitionServiceAddr, clientFactory) if err != nil { log.Printf("Warning: Failed to create competition client: %v", err) competitionClient = nil } taskClient, err := grpc_client.NewTaskClient(ctx, cfg.GRPC.TaskServiceAddr, clientFactory) if err != nil { log.Printf("Warning: Failed to create task client: %v", err) taskClient = nil } submissionClient, err := grpc_client.NewSubmissionClient(ctx, cfg.GRPC.SubmissionServiceAddr, clientFactory) if err != nil { log.Printf("Warning: Failed to create submission client: %v", err) submissionClient = nil } resultsClient, err := grpc_client.NewResultsClient(ctx, cfg.GRPC.ResultsServiceAddr, clientFactory) if err != nil { log.Printf("Warning: Failed to create results client: %v", err) resultsClient = nil } reviewClient, err := grpc_client.NewReviewClient(ctx, cfg.GRPC.ReviewServiceAddr, clientFactory) if err != nil { log.Printf("Warning: Failed to create review client: %v", err) reviewClient = nil } achievementsClient, err := grpc_client.NewAchievementsClient(ctx, cfg.GRPC.AchievementsServiceAddr, clientFactory) if err != nil { log.Printf("Warning: Failed to create achievements client: %v", err) achievementsClient = nil } s3Storage, err := storage.NewS3Storage(storage.S3Config{ AccessKeyID: cfg.S3.AccessKeyID, SecretAccessKey: cfg.S3.SecretAccessKey, Region: cfg.S3.Region, Bucket: cfg.S3.Bucket, Endpoint: cfg.S3.Endpoint, }) if err != nil { log.Fatalf("Failed to create S3 storage: %v", err) } authMiddleware := middleware.NewAuthMiddleware(authClient) var authHandler handler.AuthHandler if authClient != nil { authHandler = *handler.NewAuthHandler(authClient, userClient) } else { log.Printf("Warning: AuthHandler not initialized due to missing authClient") } var competitionHandler handler.CompetitionHandler if competitionClient != nil { competitionHandler = *handler.NewCompetitionHandler(competitionClient, userClient) } else { log.Printf("Warning: CompetitionHandler not initialized due to missing competitionClient") } var taskHandler handler.TaskHandler if taskClient != nil { taskHandler = *handler.NewTaskHandler(taskClient) } else { log.Printf("Warning: TaskHandler not initialized due to missing taskClient") } var submissionHandler handler.SubmissionHandler if submissionClient != nil { submissionHandler = *handler.NewSubmissionHandler(submissionClient, s3Storage) } else { log.Printf("Warning: SubmissionHandler not initialized due to missing submissionClient") } var resultsHandler handler.ResultsHandler if resultsClient != nil { resultsHandler = *handler.NewResultsHandler(resultsClient) } else { log.Printf("Warning: ResultsHandler not initialized due to missing resultsClient") } var reviewHandler handler.ReviewHandler if reviewClient != nil { reviewHandler = *handler.NewReviewHandler(reviewClient) } else { log.Printf("Warning: ReviewHandler not initialized due to missing reviewClient") } var achievementsHandler handler.AchievementsHandler if achievementsClient != nil { achievementsHandler = *handler.NewAchievementsHandler(achievementsClient) } else { log.Printf("Warning: AchievementsHandler not initialized due to missing achievementsClient") } pingHandler := handler.NewPingHandler() rt := router.NewRouter( &authHandler, &competitionHandler, &taskHandler, &submissionHandler, &resultsHandler, &reviewHandler, &achievementsHandler, pingHandler, authMiddleware, ) httpHandler := rt.Setup() addr := fmt.Sprintf("%s:%s", cfg.Server.Host, cfg.Server.Port) server := &http.Server{ Addr: addr, Handler: httpHandler, ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 60 * time.Second, } go func() { log.Printf("Starting API Gateway on %s", addr) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("Failed to start server: %v", err) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Println("Shutting down server...") shutdownCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := server.Shutdown(shutdownCtx); err != nil { log.Fatalf("Server forced to shutdown: %v", err) } log.Println("Server exited") }