// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package frontend provides functionality for running the pkg.go.dev site.
package frontend

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"io/fs"
	"net/http"
	hpprof "net/http/pprof"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/google/safehtml/template"
	"golang.org/x/pkgsite/internal"
	"golang.org/x/pkgsite/internal/config"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/experiment"
	pagepkg "golang.org/x/pkgsite/internal/frontend/page"
	"golang.org/x/pkgsite/internal/frontend/serrors"
	"golang.org/x/pkgsite/internal/frontend/templates"
	"golang.org/x/pkgsite/internal/frontend/urlinfo"
	"golang.org/x/pkgsite/internal/godoc/dochtml"
	"golang.org/x/pkgsite/internal/licenses"
	"golang.org/x/pkgsite/internal/log"
	"golang.org/x/pkgsite/internal/memory"
	"golang.org/x/pkgsite/internal/middleware/stats"
	"golang.org/x/pkgsite/internal/queue"
	"golang.org/x/pkgsite/internal/version"
	"golang.org/x/pkgsite/internal/vuln"
)

// Server can be installed to serve the go discovery frontend.
type Server struct {
	fetchServer FetchServerInterface
	// getDataSource should never be called from a handler. It is called only in Server.errorHandler.
	getDataSource      func(context.Context) (internal.DataSource, func())
	queue              queue.Queue
	templateFS         template.TrustedFS
	staticFS           fs.FS
	thirdPartyFS       fs.FS
	devMode            bool
	goDocMode          bool          // running to serve documentation for 'go doc'
	localMode          bool          // running locally (i.e. ./cmd/pkgsite)
	localModules       []LocalModule // locally hosted modules; empty in production
	errorPage          []byte
	appVersionLabel    string
	googleTagManagerID string
	serveStats         bool
	reporter           derrors.Reporter
	fileMux            *http.ServeMux
	vulnClient         *vuln.Client
	versionID          string
	instanceID         string
	depsDevHTTPClient  *http.Client

	mu        sync.Mutex // Protects all fields below
	templates map[string]*template.Template
}

// FetchServerInterface is an interface for the parts of the server
// that support adding packages to a queue for fetching by a worker
// server.
// TODO(matloob): rename to FetchServer once the FetchServer type moves
// to its own package
type FetchServerInterface interface {
	ServeFetch(w http.ResponseWriter, r *http.Request, ds internal.DataSource) (err error)
	ServePathNotFoundPage(w http.ResponseWriter, r *http.Request,
		ds internal.PostgresDB, fullPath, modulePath, requestedVersion string) (err error)
}

// ServerConfig contains everything needed by a Server.
type ServerConfig struct {
	Config *config.Config
	// Note that FetchServer may be nil.
	FetchServer FetchServerInterface
	// DataSourceGetter should return a DataSource and a release function on each call.
	// It should be goroutine-safe.
	DataSourceGetter  func(context.Context) (internal.DataSource, func())
	Queue             queue.Queue
	TemplateFS        template.TrustedFS // for loading templates safely
	StaticFS          fs.FS              // for static/ directory
	ThirdPartyFS      fs.FS              // for third_party/ directory
	DevMode           bool
	LocalMode         bool
	GoDocMode         bool
	LocalModules      []LocalModule
	Reporter          derrors.Reporter
	VulndbClient      *vuln.Client
	DepsDevHTTPClient *http.Client
}

// NewServer creates a new Server for the given database and template directory.
func NewServer(scfg ServerConfig) (_ *Server, err error) {
	defer derrors.Wrap(&err, "NewServer(...)")
	ts, err := templates.ParsePageTemplates(scfg.TemplateFS)
	if err != nil {
		return nil, fmt.Errorf("error parsing templates: %v", err)
	}
	dochtml.LoadTemplates(scfg.TemplateFS)
	s := &Server{
		fetchServer:       scfg.FetchServer,
		getDataSource:     scfg.DataSourceGetter,
		queue:             scfg.Queue,
		templateFS:        scfg.TemplateFS,
		staticFS:          scfg.StaticFS,
		thirdPartyFS:      scfg.ThirdPartyFS,
		devMode:           scfg.DevMode,
		localMode:         scfg.LocalMode,
		goDocMode:         scfg.GoDocMode,
		localModules:      scfg.LocalModules,
		templates:         ts,
		reporter:          scfg.Reporter,
		fileMux:           http.NewServeMux(),
		vulnClient:        scfg.VulndbClient,
		depsDevHTTPClient: scfg.DepsDevHTTPClient,
	}
	if s.depsDevHTTPClient == nil {
		s.depsDevHTTPClient = http.DefaultClient
	}
	if scfg.Config != nil {
		s.appVersionLabel = scfg.Config.AppVersionLabel()
		s.googleTagManagerID = scfg.Config.GoogleTagManagerID
		s.serveStats = scfg.Config.ServeStats
		s.versionID = scfg.Config.VersionID
		s.instanceID = scfg.Config.InstanceID
	}
	errorPageBytes, err := s.renderErrorPage(context.Background(), http.StatusInternalServerError, "error", nil)
	if err != nil {
		return nil, fmt.Errorf("s.renderErrorPage(http.StatusInternalServerError, nil): %v", err)
	}
	s.errorPage = errorPageBytes
	return s, nil
}

// A Cacher is used to create request caches for http handlers.
type Cacher interface {
	// Cache returns a new middleware that caches every request.
	// The name of the cache is used only for metrics.
	// The expirer is a func that is used to map a new request to its TTL.
	// authHeader is the header key used by the cache to know that a
	// request should bypass the cache.
	// authValues is the set of values that could be set on the authHeader in
	// order to bypass the cache.
	Cache(name string, expirer func(r *http.Request) time.Duration, authValues []string) func(http.Handler) http.Handler
}

// Install registers server routes using the given handler registration func.
// authValues is the set of values that can be set on authHeader to bypass the
// cache.
func (s *Server) Install(handle func(string, http.Handler), cacher Cacher, authValues []string) {
	var (
		detailHandler http.Handler = s.errorHandler(s.serveDetails)
		fetchHandler  http.Handler
		searchHandler http.Handler = s.errorHandler(s.serveSearch)
		vulnHandler   http.Handler = s.errorHandler(s.serveVuln)
	)
	if s.fetchServer != nil {
		fetchHandler = s.errorHandler(s.fetchServer.ServeFetch)
	}
	if cacher != nil {
		// The cache middleware uses the URL string as the key for content served
		// by the handlers it wraps. Be careful not to wrap the handler it returns
		// with a handler that rewrites the URL in a way that could cause key
		// collisions, like http.StripPrefix.
		detailHandler = cacher.Cache("details", detailsTTL, authValues)(detailHandler)
		searchHandler = cacher.Cache("search", searchTTL, authValues)(searchHandler)
		vulnHandler = cacher.Cache("vuln", vulnTTL, authValues)(vulnHandler)
	}
	// Each AppEngine instance is created in response to a start request, which
	// is an empty HTTP GET request to /_ah/start when scaling is set to manual
	// or basic, and /_ah/warmup when scaling is automatic and min_instances is
	// set. AppEngine sends this request to bring an instance into existence.
	// See details for /_ah/start at
	// https://cloud.google.com/appengine/docs/standard/go/how-instances-are-managed#startup
	// and for /_ah/warmup at
	// https://cloud.google.com/appengine/docs/standard/go/configuring-warmup-requests.
	handle("GET /_ah/", http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) {
		log.Infof(r.Context(), "Request made to %q", r.URL.Path)
	}))
	handle("GET /static/", s.staticHandler())
	handle("GET /third_party/", http.StripPrefix("/third_party", http.FileServer(http.FS(s.thirdPartyFS))))
	handle("GET /favicon.ico", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		serveFileFS(w, r, s.staticFS, "shared/icon/favicon.ico")
	}))

	handle("/sitemap/", http.StripPrefix("/sitemap/", http.FileServer(http.Dir("private/sitemap"))))
	handle("GET /mod/", http.HandlerFunc(s.handleModuleDetailsRedirect))
	handle("GET /pkg/", http.HandlerFunc(s.handlePackageDetailsRedirect))
	if fetchHandler != nil {
		handle("/fetch/", fetchHandler)
	}
	handle("POST /play/compile", http.HandlerFunc(s.proxyPlayground))
	handle("POST /play/fmt", http.HandlerFunc(s.handleFmt))
	handle("/play/share", http.HandlerFunc(s.proxyPlayground))
	handle("GET /search", searchHandler)
	handle("GET /search-help", s.staticPageHandler("search-help", "Search Help"))
	handle("GET /license-policy", s.licensePolicyHandler())
	handle("GET /about", s.staticPageHandler("about", "About"))
	handle("GET /badge/", http.HandlerFunc(s.badgeHandler))
	handle("GET /C", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Package "C" is a special case: redirect to /cmd/cgo.
		// (This is what golang.org/C does.)
		http.Redirect(w, r, "/cmd/cgo", http.StatusMovedPermanently)
	}))
	handle("GET /golang.org/x", s.staticPageHandler("subrepo", "Sub-repositories"))
	handle("GET /files/", http.StripPrefix("/files", s.fileMux))
	handle("GET /vuln/", vulnHandler)
	handle("/opensearch.xml", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		serveFileFS(w, r, s.staticFS, "shared/opensearch.xml")
	}))
	handle("/", detailHandler)
	if s.serveStats {
		handle("/detail-stats/",
			stats.Stats()(http.StripPrefix("/detail-stats", s.errorHandler(s.serveDetails))))
		handle("/search-stats/",
			stats.Stats()(http.StripPrefix("/search-stats", s.errorHandler(s.serveSearch))))
	}
	handle("/robots.txt", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
		http.ServeContent(w, r, "", time.Time{}, strings.NewReader(`User-agent: *
Disallow: /search?*
Disallow: /fetch/*
Sitemap: https://pkg.go.dev/sitemap/index.xml
`))
	}))
	s.installDebugHandlers(handle)
}

// installDebugHandlers installs handlers for debugging. Most of the handlers
// are provided by the net/http/pprof package. Although that package installs
// them on the default ServeMux in its init function, we must install them
// on our own ServeMux.
func (s *Server) installDebugHandlers(handle func(string, http.Handler)) {

	ifDebug := func(h func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			dbg := r.Header.Get(config.AllowDebugHeader)
			if dbg == "" || dbg != os.Getenv("GO_DISCOVERY_DEBUG_HEADER_VALUE") {
				http.Error(w, "not found", http.StatusNotFound)
				return
			}
			h(w, r)
		})
	}

	handle("/_debug/pprof/", ifDebug(hpprof.Index))
	handle("/_debug/pprof/cmdline", ifDebug(hpprof.Cmdline))
	handle("/_debug/pprof/profile", ifDebug(hpprof.Profile))
	handle("/_debug/pprof/symbol", ifDebug(hpprof.Symbol))
	handle("/_debug/pprof/trace", ifDebug(hpprof.Trace))

	handle("/_debug/info", ifDebug(func(w http.ResponseWriter, _ *http.Request) {
		row := func(a, b string) {
			fmt.Fprintf(w, "<tr><td>%s</td> <td>%s</td></tr>\n", a, b)
		}
		memrow := func(s string, m uint64) {
			fmt.Fprintf(w, "<tr><td>%s</td> <td align='right'>%s</td></tr>\n", s, memory.Format(m))
		}

		fmt.Fprintf(w, "<html><body style='font-family: sans-serif'>\n")

		fmt.Fprintf(w, "<table>\n")
		row("Service", os.Getenv("K_SERVICE"))
		row("Config", os.Getenv("K_CONFIGURATION"))
		row("Revision", s.versionID)
		row("Instance", s.instanceID)
		fmt.Fprintf(w, "</table>\n")

		gm := memory.ReadRuntimeStats()
		pm, err := memory.ReadProcessStats()
		if err != nil {
			http.Error(w, fmt.Sprintf("reading process stats: %v", err), http.StatusInternalServerError)
			return
		}
		sm, err := memory.ReadSystemStats()
		if err != nil {
			http.Error(w, fmt.Sprintf("reading system stats: %v", err), http.StatusInternalServerError)
			return
		}
		fmt.Fprintf(w, "<table>\n")
		memrow("Go Alloc", gm.Alloc)
		memrow("Go Sys", gm.Sys)
		memrow("Process VSize", pm.VSize)
		memrow("Process RSS", pm.RSS)
		memrow("System Total", sm.Total)
		memrow("System Used", sm.Used)
		cm, err := memory.ReadCgroupStats()
		if err != nil {
			row("CGroup Stats", "unavailable")
		} else {
			for k, v := range cm {
				memrow("CGroup "+k, v)
			}
		}
		fmt.Fprintf(w, "</table>\n")

		fmt.Fprintf(w, "</body></html>\n")

	}))
}

// InstallFS adds path under the /files handler, serving the files in fsys.
func (s *Server) InstallFS(path string, fsys fs.FS) {
	s.fileMux.Handle("GET "+path+"/", http.StripPrefix(path, http.FileServer(http.FS(fsys))))
}

const (
	// defaultTTL is used when details tab contents are subject to change, or when
	// there is a problem confirming that the details can be permanently cached.
	defaultTTL = 10 * time.Minute
	// shortTTL is used for volatile content, such as the latest version of a
	// package or module.
	shortTTL = 10 * time.Minute
	// longTTL is used when details content is essentially static.
	longTTL = 10 * time.Minute
	// tinyTTL is used to cache crawled pages.
	tinyTTL = 1 * time.Minute
	// symbolSearchTTL is used for most symbol searches.
	symbolSearchTTL = 24 * time.Hour
	// slowSymbolSearchTTL is for symbol searches that are known to be slow.
	slowSymbolSearchTTL = 14 * 24 * time.Hour
)

var crawlers = []string{
	"+http://www.google.com/bot.html",
	"+http://www.bing.com/bingbot.htm",
	"+http://ahrefs.com/robot",
}

// detailsTTL assigns the cache TTL for package detail requests.
func detailsTTL(r *http.Request) time.Duration {
	userAgent := r.Header.Get("User-Agent")
	for _, c := range crawlers {
		if strings.Contains(userAgent, c) {
			return tinyTTL
		}
	}
	return detailsTTLForPath(r.Context(), r.URL.Path, r.FormValue("tab"))
}

func detailsTTLForPath(ctx context.Context, urlPath, tab string) time.Duration {
	if urlPath == "/" {
		return defaultTTL
	}
	info, err := urlinfo.ParseDetailsURLPath(urlPath)
	if err != nil {
		log.Errorf(ctx, "falling back to default TTL: %v", err)
		return defaultTTL
	}
	if info.RequestedVersion == version.Latest {
		return shortTTL
	}
	if tab == "importedby" || tab == "versions" {
		return defaultTTL
	}
	return longTTL
}

var slowSymbolSearches = map[string]bool{
	"new":                            true,
	"version":                        true,
	"config":                         true,
	"client":                         true,
	"useragent":                      true,
	"baseclient":                     true,
	"error":                          true,
	"defaultbaseuri":                 true,
	"newwithbaseuri":                 true,
	"resource":                       true,
	"newclient":                      true,
	"get":                            true,
	"operationsclient":               true,
	"newoperationsclient":            true,
	"newoperationsclientwithbaseuri": true,
	"operation":                      true,
	"operationsclientapi":            true,
	"baseclient.baseuri":             true,
	"failed":                         true,
	"baseclient.subscriptionid":      true,
}

// searchTTL assigns the cache TTL for search requests.
func searchTTL(r *http.Request) time.Duration {
	if searchMode(r) == searchModeSymbol {
		q, _ := searchQueryAndFilters(r)
		if slowSymbolSearches[strings.ToLower(q)] {
			// Slow searches should be computed on deploy. Cache them for a long time.
			return slowSymbolSearchTTL
		}
	}
	return symbolSearchTTL
}

// vulnTTL assigns the cache TTL for vuln requests.
func vulnTTL(r *http.Request) time.Duration {
	return defaultTTL
}

// TagRoute categorizes incoming requests to the frontend for use in
// monitoring.
func TagRoute(route string, r *http.Request) string {
	tag := strings.Trim(route, "/")
	if tab := r.FormValue("tab"); tab != "" {
		// Verify that the tab value actually exists, otherwise this is unsanitized
		// input and could result in unbounded cardinality in our metrics.
		if _, ok := unitTabLookup[tab]; ok {
			if tag != "" {
				tag += "-"
			}
			tag += tab
		}
	}
	if tag == "search" {
		tag += "-" + searchMode(r)
	}
	return tag
}

// staticPageHandler handles requests to a template that contains no dynamic
// content.
func (s *Server) staticPageHandler(templateName, title string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		s.servePage(r.Context(), w, templateName, s.newBasePage(r, title))
	}
}

// LicensePolicyPage is used to generate the static license policy page.
type LicensePolicyPage struct {
	pagepkg.BasePage
	LicenseFileNames []string
	LicenseTypes     []licenses.AcceptedLicenseInfo
}

func (s *Server) licensePolicyHandler() http.HandlerFunc {
	lics := licenses.AcceptedLicenses()
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		page := LicensePolicyPage{
			BasePage:         s.newBasePage(r, "License Policy"),
			LicenseFileNames: licenses.FileNames,
			LicenseTypes:     lics,
		}
		s.servePage(r.Context(), w, "license-policy", page)
	})
}

// newBasePage returns a base page for the given request and title.
func (s *Server) newBasePage(r *http.Request, title string) pagepkg.BasePage {
	q := rawSearchQuery(r)

	var searchPrompt string
	if s.localMode {
		// Symbol search is not supported in local mode.
		searchPrompt = "Search packages"
	} else {
		searchPrompt = "Search packages or symbols"
	}

	return pagepkg.BasePage{
		HTMLTitle:          title,
		Query:              q,
		Experiments:        experiment.FromContext(r.Context()),
		DevMode:            s.devMode,
		LocalMode:          s.localMode,
		AppVersionLabel:    s.appVersionLabel,
		GoogleTagManagerID: s.googleTagManagerID,
		SearchPrompt:       searchPrompt,
		SearchModePackage:  searchModePackage,
		SearchModeSymbol:   searchModeSymbol,
		// By default, the SearchMode is set to the empty string, which
		// indicates that we should use heuristics to determine whether the
		// user wants to search for symbols or packages.
		SearchMode: "",
	}
}

// PanicHandler returns an http.HandlerFunc that can be used in HTTP
// middleware. It returns an error if something goes wrong pre-rendering the
// error template.
func (s *Server) PanicHandler() (_ http.HandlerFunc, err error) {
	defer derrors.Wrap(&err, "PanicHandler")
	status := http.StatusInternalServerError
	buf, err := s.renderErrorPage(context.Background(), status, "error", nil)
	if err != nil {
		return nil, err
	}
	return func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(status)
		if _, err := io.Copy(w, bytes.NewReader(buf)); err != nil {
			log.Errorf(r.Context(), "Error copying panic template to ResponseWriter: %v", err)
		}
	}, nil
}

func (s *Server) errorHandler(f func(w http.ResponseWriter, r *http.Request, ds internal.DataSource) error) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Obtain a DataSource to use for this request.
		ds, release := s.getDataSource(r.Context())
		defer release()
		if err := f(w, r, ds); err != nil {
			s.serveError(w, r, err)
		}
	}
}

func (s *Server) serveError(w http.ResponseWriter, r *http.Request, err error) {
	ctx := r.Context()
	var serr *serrors.ServerError
	if !errors.As(err, &serr) {
		serr = &serrors.ServerError{Status: http.StatusInternalServerError, Err: err}
	}
	if serr.Status == http.StatusInternalServerError {
		log.Error(ctx, err)
		s.reportError(ctx, err, w, r)
	} else {
		log.Infof(ctx, "returning %d (%s) for error %v", serr.Status, http.StatusText(serr.Status), err)
	}
	if serr.ResponseText == "" {
		serr.ResponseText = http.StatusText(serr.Status)
	}
	if r.Method == http.MethodPost {
		http.Error(w, serr.ResponseText, serr.Status)
		return
	}
	s.serveErrorPage(w, r, serr.Status, serr.Epage)
}

// reportError sends the error to the GCP Error Reporting service.
func (s *Server) reportError(ctx context.Context, err error, w http.ResponseWriter, r *http.Request) {
	if s.reporter == nil {
		return
	}
	// Extract the stack trace from the error if there is one.
	var stack []byte
	if serr := (*derrors.StackError)(nil); errors.As(err, &serr) {
		stack = serr.Stack
	}
	s.reporter.Report(err, r, stack)
	log.Debugf(ctx, "reported error %v with stack size %d", err, len(stack))
	// Bypass the error-reporting middleware.
	w.Header().Set(config.BypassErrorReportingHeader, "true")
}

func (s *Server) serveErrorPage(w http.ResponseWriter, r *http.Request, status int, page *pagepkg.ErrorPage) {
	template := "error"
	if page != nil {
		if page.AppVersionLabel == "" || page.GoogleTagManagerID == "" {
			// If the BasePage was properly created using newBasePage, both
			// AppVersionLabel and GoogleTagManagerID should always be set.
			page.BasePage = s.newBasePage(r, "")
		}
		if page.TemplateName != "" {
			template = page.TemplateName
		}
	} else {
		page = &pagepkg.ErrorPage{
			BasePage: s.newBasePage(r, ""),
		}
	}
	buf, err := s.renderErrorPage(r.Context(), status, template, page)
	if err != nil {
		log.Errorf(r.Context(), "s.renderErrorPage(w, %d, %v): %v", status, page, err)
		buf = s.errorPage
		status = http.StatusInternalServerError
	}

	w.WriteHeader(status)
	if _, err := io.Copy(w, bytes.NewReader(buf)); err != nil {
		log.Errorf(r.Context(), "Error copying template %q buffer to ResponseWriter: %v", template, err)
	}
}

// renderErrorPage executes error.tmpl with the given ErrorPage
func (s *Server) renderErrorPage(ctx context.Context, status int, templateName string, page *pagepkg.ErrorPage) ([]byte, error) {
	statusInfo := fmt.Sprintf("%d %s", status, http.StatusText(status))
	if page == nil {
		page = &pagepkg.ErrorPage{}
	}
	if page.MessageTemplate.String() == "" {
		page.MessageTemplate = template.MakeTrustedTemplate(`<h3 class="Error-message">{{.}}</h3>`)
	}
	if page.MessageData == nil {
		page.MessageData = statusInfo
	}
	if page.HTMLTitle == "" {
		page.HTMLTitle = statusInfo
	}
	if templateName == "" {
		templateName = "error"
	}

	etmpl, err := s.findTemplate(templateName)
	if err != nil {
		return nil, err
	}
	tmpl, err := etmpl.Clone()
	if err != nil {
		return nil, err
	}
	_, err = tmpl.New("message").ParseFromTrustedTemplate(page.MessageTemplate)
	if err != nil {
		return nil, err
	}

	return executeTemplate(ctx, templateName, tmpl, page)
}

// servePage is used to execute all templates for a *Server.
func (s *Server) servePage(ctx context.Context, w http.ResponseWriter, templateName string, page any) {
	defer stats.Elapsed(ctx, "servePage")()

	buf, err := s.renderPage(ctx, templateName, page)
	if err != nil {
		log.Errorf(ctx, "s.renderPage(%q, %+v): %v", templateName, page, err)
		w.WriteHeader(http.StatusInternalServerError)
		buf = s.errorPage
	}
	if _, err := io.Copy(w, bytes.NewReader(buf)); err != nil {
		log.Errorf(ctx, "Error copying template %q buffer to ResponseWriter: %v", templateName, err)
		w.WriteHeader(http.StatusInternalServerError)
	}
}

// renderPage executes the given templateName with page.
func (s *Server) renderPage(ctx context.Context, templateName string, page any) ([]byte, error) {
	defer stats.Elapsed(ctx, "renderPage")()

	tmpl, err := s.findTemplate(templateName)
	if err != nil {
		return nil, err
	}
	return executeTemplate(ctx, templateName, tmpl, page)
}

func (s *Server) findTemplate(templateName string) (*template.Template, error) {
	if s.devMode {
		s.mu.Lock()
		defer s.mu.Unlock()
		var err error
		s.templates, err = templates.ParsePageTemplates(s.templateFS)
		if err != nil {
			return nil, fmt.Errorf("error parsing templates: %v", err)
		}
	}
	tmpl := s.templates[templateName]
	if tmpl == nil {
		return nil, fmt.Errorf("BUG: s.templates[%q] not found", templateName)
	}
	return tmpl, nil
}

func executeTemplate(ctx context.Context, templateName string, tmpl *template.Template, data any) ([]byte, error) {
	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, data); err != nil {
		log.Errorf(ctx, "Error executing page template %q: %v", templateName, err)
		return nil, err
	}
	return buf.Bytes(), nil
}

func (s *Server) staticHandler() http.Handler {
	return http.StripPrefix("/static/", http.FileServer(http.FS(s.staticFS)))
}

// serveFileFS serves a file from the given filesystem.
func serveFileFS(w http.ResponseWriter, r *http.Request, fsys fs.FS, name string) {
	fs := http.FileServer(http.FS(fsys))
	r.URL.Path = name
	fs.ServeHTTP(w, r)
}
