package httpapi import ( "encoding/json" "net/http" "strings" "time" "github.com/go-chi/chi/v5" "github.com/benya/temporserv/internal/auth" "github.com/benya/temporserv/internal/config" "github.com/benya/temporserv/internal/library" "github.com/benya/temporserv/internal/subsonic" ) func NewRouter(cfg config.Config) http.Handler { r := chi.NewRouter() r.Use(requestLogger) r.Use(recoverer) r.Use(cors(cfg.CORSOrigins)) r.Get("/health", func(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, map[string]any{ "status": "ok", "time": time.Now().UTC(), "env": cfg.AppEnv, }) }) r.Route("/api", func(api chi.Router) { api.Get("/me", func(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, auth.DemoUser()) }) api.Get("/home", func(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, library.DemoHome()) }) api.Get("/tracks", func(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, map[string]any{ "items": library.DemoTracks(), }) }) api.Post("/auth/login", func(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, map[string]any{ "token": "dev-token", "user": auth.DemoUser(), }) }) }) r.Route("/rest", func(rest chi.Router) { rest.Get("/ping.view", func(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, subsonic.PingResponse()) }) rest.Get("/getLicense.view", func(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, subsonic.PingResponse()) }) }) fs := http.FileServer(http.Dir("./web")) r.Handle("/*", spaFallback(fs)) return r } func writeJSON(w http.ResponseWriter, status int, payload any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) _ = json.NewEncoder(w).Encode(payload) } func spaFallback(next http.Handler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if strings.HasPrefix(r.URL.Path, "/api") || strings.HasPrefix(r.URL.Path, "/rest") || strings.HasPrefix(r.URL.Path, "/health") { http.NotFound(w, r) return } next.ServeHTTP(w, r) } }