package web

import (
	"net/http"
	"path"
	"strings"

	"github.com/go-chi/chi/v5"
)

// Register mounts every compare.sr.ht route onto r. The caller is responsible
// for installing the middleware documented on the package (config + authz at a
// minimum); Register adds no middleware of its own.
func (s *Server) Register(r chi.Router) {
	r.Get("/", s.handleIndex)
	r.Get("/jump", s.handleJump)
	r.Get("/healthz", s.handleHealthz)
	r.Get("/static/*", s.handleStatic)

	r.Get("/~{owner}/{repo}", s.handleRepo)
	// A single wildcard route serves both the form target (empty wildcard ⇒
	// redirect to the canonical URL) and the compare view itself.
	r.Get("/~{owner}/{repo}/compare/*", s.handleCompare)
	r.Get("/~{owner}/{repo}/commit/{rev}", s.handleCommit)
}

// handleHealthz is a dependency-free liveness probe.
func (s *Server) handleHealthz(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	_, _ = w.Write([]byte("ok\n"))
}

// handleStatic serves the embedded assets, tagging the content-addressed
// stylesheet as immutable and forcing a JS content type for the bundle.
func (s *Server) handleStatic(w http.ResponseWriter, r *http.Request) {
	name := path.Base(r.URL.Path)
	if strings.HasSuffix(name, ".js") {
		w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
	}
	if hashedCSSRe.MatchString(name) || hashedBundleRe.MatchString(name) {
		w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
	} else {
		w.Header().Set("Cache-Control", "public, max-age=3600")
	}
	s.staticFileServer.ServeHTTP(w, r)
}

// handleJump powers the owner/repo jump form: it redirects to the canonical repo
// URL. A leading "~" on the owner is tolerated.
func (s *Server) handleJump(w http.ResponseWriter, r *http.Request) {
	owner := strings.TrimPrefix(strings.TrimSpace(r.URL.Query().Get("owner")), "~")
	repo := strings.TrimSpace(r.URL.Query().Get("repo"))
	if owner == "" || repo == "" {
		s.renderError(w, r, http.StatusBadRequest, "both owner and repository are required")
		return
	}
	http.Redirect(w, r, "/~"+owner+"/"+repo, http.StatusFound)
}
