package server import ( "context" "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" "gitcitadel-online/internal/cache" "gitcitadel-online/internal/nostr" ) // Server represents the HTTP server type Server struct { httpServer *http.Server cache *cache.Cache feedCache *cache.FeedCache port int issueService IssueServiceInterface repoAnnouncement string htmlGenerator HTMLGeneratorInterface } // IssueServiceInterface defines the interface for issue service type IssueServiceInterface interface { FetchRepoAnnouncement(ctx context.Context, repoNaddr string) (*nostr.RepoAnnouncement, error) PublishIssue(ctx context.Context, repoAnnouncement *nostr.RepoAnnouncement, req *nostr.IssueRequest, privateKey string) (string, error) } // HTMLGeneratorInterface defines the interface for HTML generator type HTMLGeneratorInterface interface { GenerateContactPage(success bool, errorMsg string, eventID string, formData map[string]string) (string, error) } // NewServer creates a new HTTP server func NewServer(port int, pageCache *cache.Cache, feedCache *cache.FeedCache, issueService IssueServiceInterface, repoAnnouncement string, htmlGenerator HTMLGeneratorInterface) *Server { s := &Server{ cache: pageCache, feedCache: feedCache, port: port, issueService: issueService, repoAnnouncement: repoAnnouncement, htmlGenerator: htmlGenerator, } mux := http.NewServeMux() // Setup routes s.setupRoutes(mux) s.httpServer = &http.Server{ Addr: fmt.Sprintf(":%d", port), Handler: s.middleware(mux), ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 60 * time.Second, } return s } // Start starts the HTTP server func (s *Server) Start() error { log.Printf("Starting server on port %d", s.port) return s.httpServer.ListenAndServe() } // Shutdown gracefully shuts down the server func (s *Server) Shutdown(ctx context.Context) error { return s.httpServer.Shutdown(ctx) } // WaitForShutdown waits for shutdown signals func (s *Server) WaitForShutdown() { quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Println("Shutting down server...") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := s.Shutdown(ctx); err != nil { log.Fatal("Server forced to shutdown:", err) } log.Println("Server exited") }