package cmd import ( "net/http" "os" "strings" apimiddleware "clintonambulance.com/calculate_negative_points/internal/api/middleware" "clintonambulance.com/calculate_negative_points/internal/config" "clintonambulance.com/calculate_negative_points/internal/server" "clintonambulance.com/calculate_negative_points/internal/utils" "github.com/go-chi/chi/v5" "github.com/swaggest/rest/web" "go.uber.org/zap" ) func Execute(version config.Version) { logger, flushLogs := config.NewLogger(version, os.Stdout, os.Args) defer flushLogs() configuration := utils.Must(config.Load(version, os.Exit, os.Args, logger))(logger) logger.Info("Application startup", zap.Any("config", configuration), zap.Any("full_version", version)) srv, _ := server.NewHttpServer(logger, version) FileServer(srv, "/assets/", configuration.PublicPath, logger) server.MountAllEndpoints(srv, version, configuration, logger) srv.NotFound(func(w http.ResponseWriter, _ *http.Request) { apimiddleware.ErrorResponder(w, "Not Found", http.StatusNotFound) }) srv.MethodNotAllowed(func(w http.ResponseWriter, _ *http.Request) { apimiddleware.ErrorResponder(w, "Method Not Allowed", http.StatusMethodNotAllowed) }) if err := http.ListenAndServe(configuration.Listen, srv); err != nil { logger.Fatal("HTTP server error", zap.Error(err)) } } func FileServer(r *web.Service, path string, rootPath string, logger *zap.Logger) { root := http.Dir(rootPath) if strings.ContainsAny(path, "{}*") { panic("FileServer does not permit any URL parameters.") } path += "*" r.Wrapper.Get(path, func(w http.ResponseWriter, r *http.Request) { rctx := chi.RouteContext(r.Context()) pathPrefix := strings.TrimSuffix(rctx.RoutePattern(), "/*") logger.Info("Serving file", zap.String("root_path", rootPath), zap.String("pathPrefix", pathPrefix), zap.String("rawPath", r.URL.Path)) fs := http.FileServer(root) fs.ServeHTTP(w, r) }) }