// Copyright 2009 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.

// Golangorg serves the golang.org web sites.
package main

import (
	"archive/zip"
	"bytes"
	"context"
	"embed"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"html/template"
	"io"
	"io/fs"
	"log"
	"net/http"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"runtime/debug"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"cloud.google.com/go/datastore"
	"golang.org/x/build/relnote"
	"golang.org/x/build/repos"
	"golang.org/x/website"
	"golang.org/x/website/internal/blog"
	"golang.org/x/website/internal/codewalk"
	"golang.org/x/website/internal/dl"
	"golang.org/x/website/internal/gitfs"
	"golang.org/x/website/internal/history"
	"golang.org/x/website/internal/memcache"
	"golang.org/x/website/internal/pkgdoc"
	"golang.org/x/website/internal/play"
	"golang.org/x/website/internal/redirect"
	"golang.org/x/website/internal/short"
	"golang.org/x/website/internal/talks"
	"golang.org/x/website/internal/tour"
	"golang.org/x/website/internal/web"
	"golang.org/x/website/internal/webtest"
	"rsc.io/markdown"
)

var (
	httpAddr   = flag.String("http", "localhost:6060", "HTTP service address")
	verbose    = flag.Bool("v", false, "verbose mode")
	goroot     = flag.String("goroot", runtime.GOROOT(), "Go root directory")
	contentDir = flag.String("content", "", "path to _content directory")

	runningOnAppEngine = os.Getenv("PORT") != ""
	forceGorootZip, _  = strconv.ParseBool(os.Getenv("GOLANGORG_FORCE_GOROOT_ZIP"))

	tipFlag   = flag.Bool("tip", runningOnAppEngine, "load git content for tip.golang.org")
	wikiFlag  = flag.Bool("wiki", runningOnAppEngine, "load git content for go.dev/wiki")
	goplsFlag = flag.Bool("gopls", runningOnAppEngine, "load git content for go.dev/gopls")

	googleAnalytics string
)

func usage() {
	fmt.Fprintf(os.Stderr, "usage: golangorg\n")
	flag.PrintDefaults()
	os.Exit(2)
}

func main() {
	flag.Usage = usage
	flag.Parse()

	// Running locally, find the local _content directory when it's available nearby,
	// so that updates to those files appear on the local dev instance without restarting.
	// On App Engine, leave contentDir empty, so we use the embedded copy,
	// which is much faster to access than the simulated file system.
	if *contentDir == "" && !runningOnAppEngine {
		if fi, err := os.Stat(filepath.Join("..", "..", "_content")); err == nil && fi.IsDir() {
			*contentDir = filepath.Join("..", "..", "_content")
		} else if fi, err := os.Stat("_content"); err == nil && fi.IsDir() {
			*contentDir = "_content"
		} else {
			*contentDir = "" // Fall back to using embedded content.
		}
	}

	if forceGorootZip {
		*goroot = "_goroot.zip"
	}

	if runningOnAppEngine {
		log.Print("golang.org server starting")
		log.SetFlags(log.Lshortfile | log.LstdFlags)
		port := "8080"
		if p := os.Getenv("PORT"); p != "" {
			port = p
		}
		*httpAddr = ":" + port
	}

	// Check usage.
	if flag.NArg() > 0 {
		fmt.Fprintln(os.Stderr, "Unexpected arguments.")
		usage()
	}
	if *httpAddr == "" {
		fmt.Fprintln(os.Stderr, "-http must be set")
		usage()
	}

	handler := NewHandler(*contentDir, *goroot)
	handler = webtest.HandlerWithCheck(handler, "/_readycheck",
		testdataFS, "testdata/*.txt")

	if *verbose {
		log.Printf("golang.org server:")
		log.Printf("\tversion = %s", runtime.Version())
		log.Printf("\taddress = %s", *httpAddr)
		log.Printf("\tgoroot = %s", *goroot)
		log.Printf("\tcontent = %s", contentSource())
		handler = loggingHandler(handler)
	}

	// Start http server.
	fmt.Fprintf(os.Stderr, "serving http://%s\n", *httpAddr)
	if err := http.ListenAndServe(*httpAddr, handler); err != nil {
		log.Fatalf("ListenAndServe %s: %v", *httpAddr, err)
	}
}

// contentSource returns a human-readable description
// of where the x/website _content dir is coming from.
func contentSource() string {
	if *contentDir == "" {
		return "embedded content"
	} else if abs, err := filepath.Abs(*contentDir); err == nil {
		return abs
	} else {
		return *contentDir
	}
}

//go:embed testdata
var testdataFS embed.FS

// NewHandler returns the http.Handler for the web site,
// given the directory where the content can be found
// (can be "", in which case an internal copy is used)
// and the directory or zip file of the GOROOT.
func NewHandler(contentDir, goroot string) http.Handler {
	mux := http.NewServeMux()

	// Serve files from _content, falling back to GOROOT.

	// Use explicit contentDir if specified, otherwise embedded copy.
	var contentFS fs.FS
	if contentDir != "" {
		contentFS = os.DirFS(contentDir)
	} else {
		contentFS = website.Content()
	}

	var gorootFS fs.FS
	if strings.HasSuffix(goroot, ".zip") {
		z, err := zip.OpenReader(goroot)
		if err != nil {
			log.Fatal(err)
		}
		gorootFS = &seekableFS{z}
	} else {
		gorootFS = os.DirFS(goroot)
	}

	// go.dev/wiki serves content from the very latest Git commit of the wiki repo.
	// Start with the _content/wiki directory as placeholder until Git loads.
	var wikiFS atomicFS
	wikiDefault, err := fs.Sub(contentFS, "wiki")
	if err != nil {
		log.Fatalf("loading default wiki content: %v", err)
	}
	wikiFS.Set(wikiDefault)
	if *wikiFlag {
		go watchGit(&wikiFS, "https://go.googlesource.com/wiki", "HEAD")
	}
	contentFS = &mountFS{contentFS, "wiki", &wikiFS}

	// tip.golang.org serves content from the very latest Git commit
	// of the main Go repo, instead of the one the app is bundled with.
	//
	// tip.golang.org/gopls serves the latest commit of golang.org/x/tools/gopls/doc.
	var tipGoroot atomicFS
	if _, err := newSite(mux, "tip.golang.org", addGopls(contentFS, "HEAD"), &tipGoroot); err != nil {
		log.Fatalf("loading tip site: %v", err)
	}
	if *tipFlag {
		go watchGit(&tipGoroot, "https://go.googlesource.com/go", "HEAD")
	}

	// go.dev/gopls serves golang.org/x/tools/gopls/doc from the
	// tip commit on the latest release branch.
	contentFS = addGopls(contentFS, "gopls/latest-release-branch")

	// beta.golang.org is an old name for tip.
	mux.Handle("beta.golang.org/", redirectPrefix("https://tip.golang.org/"))

	// By default, golang.org/foo redirects to go.dev/foo.
	// All the user-facing golang.org subdomains have moved to go.dev subdirectories.
	// There are some exceptions below, like for golang.org/x.
	mux.Handle("golang.org/", redirectPrefix("https://go.dev/"))
	mux.Handle("blog.golang.org/", redirectPrefix("https://go.dev/blog/"))
	mux.Handle("learn.go.dev/", redirectPrefix("https://go.dev/learn/"))
	mux.Handle("talks.golang.org/", redirectPrefix("https://go.dev/talks/"))
	mux.Handle("tour.golang.org/", redirectPrefix("https://go.dev/tour/"))

	// Redirect subdirectory-like domains to the actual subdirectories,
	// for people whose fingers learn to type go.dev instead of golang.org
	// but not the rest of the URL schema change.
	// Note that these domains have to be listed in knownHosts below as well.
	mux.Handle("blog.go.dev/", redirectPrefix("https://go.dev/blog/"))
	mux.Handle("play.go.dev/", redirectPrefix("https://go.dev/play/"))
	mux.Handle("talks.go.dev/", redirectPrefix("https://go.dev/talks/"))
	mux.Handle("tour.go.dev/", redirectPrefix("https://go.dev/tour/"))

	// m.golang.org is an old shortcut for golang.org mail.
	// Gmail itself can serve this redirect, but only on HTTP (not HTTPS).
	// Golang.org's HSTS header tells browsers to use HTTPS for all subdomains,
	// which broke the redirect.
	mux.Handle("m.golang.org/", http.RedirectHandler("https://mail.google.com/a/golang.org/", http.StatusMovedPermanently))

	// Redirect synthetic subtrees on tip.golang.org over to go.dev.
	tipRedirects := []string{
		"blog",
		"cl", "change",
		"design",
		"dl",
		"issue", "issues",
		"s",
		"talks",
		"tour",
	}
	for _, name := range tipRedirects {
		mux.Handle("tip.golang.org/"+name+"/", redirectPrefix("https://go.dev/"))
	}
	// tip.golang.org/play redirect adds ?v=gotip so the playground defaults to tip.
	mux.Handle("tip.golang.org/play/", redirectPrefixQuery("https://go.dev/", "v=gotip"))

	// TODO(rsc): The unionFS is a hack until we move the files in a followup CL.
	siteMux := http.NewServeMux()
	godevSite, err := newSite(siteMux, "", contentFS, gorootFS)
	if err != nil {
		log.Fatalf("newSite go.dev: %v", err)
	}
	chinaSite, err := newSite(siteMux, "golang.google.cn", contentFS, gorootFS)
	if err != nil {
		log.Fatalf("newSite golang.google.cn: %v", err)
	}
	if runningOnAppEngine {
		appEngineSetup(mux)
	}
	dl.RegisterHandlers(siteMux, godevSite, "", datastoreClient, memcacheClient)
	dl.RegisterHandlers(siteMux, chinaSite, "golang.google.cn", datastoreClient, memcacheClient)
	mux.Handle("/", siteMux)

	play.RegisterHandlers(mux, godevSite, chinaSite)

	mux.Handle("/explore/", http.StripPrefix("/explore/", redirectPrefix("https://pkg.go.dev/")))
	if err := blog.RegisterFeeds(mux, "", godevSite); err != nil {
		log.Fatalf("blog: %v", err)
	}

	// Note: Only golang.org/x/, no go.dev/x/.
	mux.Handle("golang.org/x/", http.HandlerFunc(xHandler))
	mux.Handle("golang.org/toolchain", http.HandlerFunc(toolchainHandler))

	redirect.Register(mux)

	// Note: Using godevSite (non-China) for global mux registration because there's no sharing in talks.
	// Don't need the hassle of two separate registrations for different domains in siteMux.
	if err := talks.RegisterHandlers(mux, godevSite, contentFS); err != nil {
		log.Fatalf("talks: %v", err)
	}
	if err := tour.RegisterHandlers(mux); err != nil {
		log.Fatalf("tour: %v", err)
	}

	var h http.Handler = mux
	h = addCSP(mux)
	h = hostEnforcerHandler(h)
	h = hostPathHandler(h)
	return h
}

// addGopls registers the /gopls endpoint to serve
// golang.org/x/tools/gopls/doc, depending on ref, at either the
// latest Gopls release or the latest x/tools commit.
func addGopls(contentFS fs.FS, ref string) fs.FS {
	var toolsFS atomicFS

	// Before the first git clone completes,
	// serve _content/gopls/doc as placeholder.
	toolsFS.Set(contentFS)

	// To load file content from a local x/tools directory
	// for ease of debugging, set this env var.
	if dir, ok := os.LookupEnv("GOLANGORG_LOCAL_X_TOOLS"); ok {
		log.Printf("using local golang.org/x/tools dir %s", dir)
		toolsFS.Set(os.DirFS(dir))

	} else if !*tipFlag && ref == "HEAD" {
		// The intent of -tip=false is to avoid fetching repos
		// not needed tip.golang.org. We assume here that
		// ref=HEAD means we're working for tip.golang.org/gopls;
		// don't fetch x/tools in that case.

	} else if *goplsFlag {
		go watchGit(&toolsFS, "https://go.googlesource.com/tools", ref)
	}

	goplsDocFS, err := fs.Sub(&toolsFS, "gopls/doc")
	if err != nil {
		log.Fatalf("can't restrict to gopls/doc tree: %v", err)
	}
	return &mountFS{contentFS, "gopls", goplsDocFS}
}

var gorebuild = NewCachedURL("https://gorebuild.storage.googleapis.com/gorebuild.json", 5*time.Minute)

// newSite creates a new site for a given content and goroot file system pair
// and registers it in mux to handle requests for host.
// If host is the empty string, the registrations are for the wildcard host.
func newSite(mux *http.ServeMux, host string, content, goroot fs.FS) (*web.Site, error) {
	fsys := unionFS{content, &hideRootMDFS{&fixSpecsFS{goroot}}}
	site := web.NewSite(fsys)
	site.Funcs(template.FuncMap{
		"googleAnalytics": func() string { return googleAnalytics },
		"googleCN":        func() bool { return host == "golang.google.cn" },
		"gorebuild":       gorebuild.Get,
		"json":            jsonUnmarshal,
		"newest":          newest,
		"now":             func() time.Time { return time.Now() },
		"releases":        func() []*history.Major { return history.Majors },
		"rfc3339":         parseRFC3339,
		"section":         section,
		"version":         func() string { return runtime.Version() },
		"docNext":         releaseNotePreview{goroot}.MergedFragments,
	})
	docs, err := pkgdoc.NewServer(fsys, site, googleCN)
	if err != nil {
		return nil, err
	}

	mux.Handle(host+"/", site)
	mux.Handle(host+"/cmd/", docs)
	mux.Handle(host+"/pkg/", docs)
	mux.Handle(host+"/doc/codewalk/", codewalk.NewServer(fsys, site))
	return site, nil
}

// releaseNotePreview implements a preview of upcoming release notes.
type releaseNotePreview struct {
	goroot fs.FS // goroot provides the doc/next content to use, if any.
}

// MergedFragments returns Markdown obtained by merging release note fragments
// found in the doc/next directory in goroot, to preview relnote generate output.
// An empty string and no error is returned if the doc/next directory doesn't exist.
func (p releaseNotePreview) MergedFragments() (markdownWithEmbeddedHTML template.HTML, _ error) {
	next, err := fs.Sub(p.goroot, "doc/next")
	if err != nil {
		return "", err
	}
	if _, err := fs.Stat(next, "."); os.IsNotExist(err) || errors.Is(err, errNoFileSystem) {
		// No next release note fragments.
		return "", nil
	}
	doc, err := relnote.Merge(next)
	if err != nil {
		return "", fmt.Errorf("relnote.Merge: %v", err)
	}
	// Note: It's possible to render doc, a parsed Markdown document with embedded HTML,
	// into Markdown or HTML. We choose to render to Markdown and let x/website/internal/web
	// handle the remaining conversion to HTML. This means the rendering is more consistent
	// with what'll happen when relnote generate output is added as _content/doc/go1.N.md.
	return template.HTML(markdown.ToMarkdown(doc)), nil
}

func parseRFC3339(s string) (time.Time, error) {
	return time.Parse(time.RFC3339, s)
}

// watchGit is a background goroutine that watches a Git repo for updates.
// When the ref (e.g. "HEAD") refers to a new commit, watchGit downloads the new tree and calls
// fsys.Set to install the new file system.
func watchGit(fsys *atomicFS, repo, ref string) {
	for {
		// watchGit1 runs until it panics (hopefully never).
		// If that happens, sleep 5 minutes and try again.
		watchGit1(fsys, repo, ref)
		time.Sleep(5 * time.Minute)
	}
}

// watchGit1 does the actual work of watchGit and recovers from panics.
func watchGit1(afs *atomicFS, repo, ref string) {
	defer func() {
		if e := recover(); e != nil {
			log.Printf("watchGit %s panic: %v\n%s", repo, e, debug.Stack())
		}
	}()

	var r *gitfs.Repo
	for {
		var err error
		r, err = gitfs.NewRepo(repo)
		if err != nil {
			log.Printf("watchGit %s: %v", repo, err)
			time.Sleep(1 * time.Minute)
			continue
		}
		break
	}

	var h gitfs.Hash
	for {
		var fsys fs.FS
		var err error
		h, fsys, err = r.Clone(ref)
		if err != nil {
			log.Printf("watchGit %s: %v", repo, err)
			time.Sleep(1 * time.Minute)
			continue
		}
		afs.Set(fsys)
		break
	}

	for {
		time.Sleep(5 * time.Minute)
		h2, err := r.Resolve(ref)
		if err != nil {
			log.Printf("watchGit %s: %v", repo, err)
			continue
		}
		if h2 != h {
			fsys, err := r.CloneHash(h2)
			if err != nil {
				log.Printf("watchGit %s: %v", repo, err)
				time.Sleep(1 * time.Minute)
				continue
			}
			afs.Set(fsys)
			h = h2
		}
	}
}

var (
	datastoreClient *datastore.Client
	memcacheClient  *memcache.Client
)

func appEngineSetup(mux *http.ServeMux) {
	googleAnalytics = os.Getenv("GOLANGORG_ANALYTICS")

	ctx := context.Background()

	var err error
	datastoreClient, err = datastore.NewClient(ctx, "")
	if err != nil {
		if strings.Contains(err.Error(), "missing project") {
			log.Fatalf("Missing datastore project. Set the DATASTORE_PROJECT_ID env variable. Use `gcloud beta emulators datastore` to start a local datastore.")
		}
		log.Fatalf("datastore.NewClient: %v.", err)
	}

	redisAddr := os.Getenv("GOLANGORG_REDIS_ADDR")
	if redisAddr == "" {
		log.Fatalf("Missing redis server for golangorg in production mode. set GOLANGORG_REDIS_ADDR environment variable.")
	}
	memcacheClient = memcache.New(redisAddr)

	short.RegisterHandlers(mux, "", datastoreClient, memcacheClient)

	log.Println("AppEngine initialization complete")
}

type fmtResponse struct {
	Body  string
	Error string
}

var validHosts = map[string]bool{
	"golang.org":       true,
	"golang.google.cn": true,
	"beta.golang.org":  true,
	"blog.golang.org":  true,
	"m.golang.org":     true,
	"talks.golang.org": true,
	"tip.golang.org":   true,
	"tour.golang.org":  true,

	"go.dev":       true,
	"blog.go.dev":  true,
	"learn.go.dev": true,
	"play.go.dev":  true,
	"talks.go.dev": true,
	"tour.go.dev":  true,
}

// hostEnforcerHandler redirects http://foo.golang.org/bar to https://golang.org/bar.
// It also forces all requests coming from China for golang.org to use golang.google.cn.
func hostEnforcerHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		isHTTPS := r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https" || r.URL.Scheme == "https"
		defaultHost := "go.dev"
		host := strings.ToLower(r.Host)
		isValidHost := validHosts[host]

		if googleCN(r) && !strings.HasSuffix(host, "google.cn") {
			// golang.google.cn is the only web site in China.
			defaultHost = "golang.google.cn"
			isValidHost = strings.ToLower(r.Host) == defaultHost
		}

		if !isHTTPS || !isValidHost {
			r.URL.Scheme = "https"
			if isValidHost {
				r.URL.Host = r.Host
			} else {
				r.URL.Host = defaultHost
			}
			http.Redirect(w, r, r.URL.String(), http.StatusFound)
			return
		}

		w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
		h.ServeHTTP(w, r)
	})
}

// hostPathHandler infers the host from the first element of the URL path
// when the actual host is a testing domain (localhost or *.appspot.com).
// It also rewrites the output HTML and Location headers in that case to
// link back to URLs on the test site.
func hostPathHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Host != "localhost" && !strings.HasPrefix(r.Host, "localhost:") && !strings.HasSuffix(r.Host, ".appspot.com") {
			h.ServeHTTP(w, r)
			return
		}

		elem, rest := strings.TrimPrefix(r.URL.Path, "/"), ""
		if i := strings.Index(elem, "/"); i >= 0 {
			if elem[:i] == "tour" {
				// The Angular router serving /tour/ fails badly when it sees /go.dev/tour/.
				// Just take http://localhost/tour/ as meaning /go.dev/tour/ instead of redirecting.
				elem, rest = "go.dev", elem
			} else {
				elem, rest = elem[:i], elem[i+1:]
			}
		}
		if !validHosts[elem] {
			u := "/go.dev" + r.URL.EscapedPath()
			if r.URL.RawQuery != "" {
				u += "?" + r.URL.RawQuery
			}
			http.Redirect(w, r, u, http.StatusTemporaryRedirect)
			return
		}

		r.Host = elem
		r.URL.Scheme = "https"
		r.URL.Host = elem
		r.URL.Path = "/" + rest

		log.Print(r.URL.String())

		lw := &linkRewriter{ResponseWriter: w, host: r.Host, tour: strings.HasPrefix(r.URL.Path, "/tour/")}
		h.ServeHTTP(lw, r)
		lw.Flush()
	})
}

// A linkRewriter is a ResponseWriter that rewrites links in HTML output.
// It rewrites relative links /foo to be /host/foo, and it rewrites any link
// https://h/foo, where h is in validHosts, to be /h/foo. This corrects the
// links to have the right form for the test server.
type linkRewriter struct {
	http.ResponseWriter
	host string
	tour bool // is this go.dev/tour/?
	buf  []byte
	ct   string // content-type
}

func (r *linkRewriter) WriteHeader(code int) {
	loc := r.Header().Get("Location")
	delete(r.Header(), "Content-Length") // we might change the content
	if strings.HasPrefix(loc, "/") && !strings.HasPrefix(loc, "/tour/") {
		r.Header().Set("Location", "/"+r.host+loc)
	} else if u, _ := url.Parse(loc); u != nil && validHosts[u.Host] {
		r.Header().Set("Location", "/"+u.Host+"/"+strings.TrimPrefix(u.Path, "/")+u.RawQuery)
	}
	r.ResponseWriter.WriteHeader(code)
}

func (r *linkRewriter) Write(data []byte) (int, error) {
	if r.ct == "" {
		ct := r.Header().Get("Content-Type")
		if ct == "" {
			// Note: should use first 512 bytes, but first write is fine for our purposes.
			ct = http.DetectContentType(data)
		}
		r.ct = ct
	}
	if !strings.HasPrefix(r.ct, "text/html") {
		return r.ResponseWriter.Write(data)
	}
	r.buf = append(r.buf, data...)
	return len(data), nil
}

func (r *linkRewriter) Flush() {
	var repl []string
	if !r.tour {
		repl = []string{
			`href="/`, `href="/` + r.host + `/`,
			`src="/`, `src="/` + r.host + `/`,
		}
	}
	for host := range validHosts {
		repl = append(repl, `href="https://`+host, `href="/`+host)
		repl = append(repl, `src="https://`+host, `src="/`+host)
	}
	strings.NewReplacer(repl...).WriteString(r.ResponseWriter, string(r.buf))
	r.buf = nil
}

func loggingHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("%s\t%s", r.RemoteAddr, r.URL)
		h.ServeHTTP(w, r)
	})
}

func xHandler(w http.ResponseWriter, r *http.Request) {
	if !strings.HasPrefix(r.URL.Path, "/x/") {
		// Shouldn't happen if handler is registered correctly.
		http.Redirect(w, r, "https://pkg.go.dev/golang.org/x", http.StatusTemporaryRedirect)
		return
	}
	proj, suffix := strings.TrimPrefix(r.URL.Path, "/x/"), ""
	if i := strings.Index(proj, "/"); i != -1 {
		proj, suffix = proj[:i], proj[i:]
	}
	if proj == "" {
		http.Redirect(w, r, "https://pkg.go.dev/golang.org/x", http.StatusTemporaryRedirect)
		return
	}
	repo, ok := repos.ByGerritProject[proj]
	if !ok || !strings.HasPrefix(repo.ImportPath, "golang.org/x/") {
		http.NotFound(w, r)
		return
	}
	if suffix == "/info/refs" && strings.HasPrefix(r.URL.Query().Get("service"), "git-") && repo.GoGerritProject != "" {
		// Someone is running 'git clone https://golang.org/x/repo'.
		// We want the eventual git checkout to have the right origin (go.googlesource.com)
		// and not just keep hitting golang.org all the time.
		// A redirect would work for this git command but not record the result.
		// Instead, print a useful error for the user.
		http.Error(w, fmt.Sprintf("Use 'git clone https://go.googlesource.com/%s' instead.", repo.GoGerritProject), http.StatusNotFound)
		return
	}
	data := struct {
		Proj   string // Gerrit project ("net", "sys", etc)
		Suffix string // optional "/path" for requests like /x/PROJ/path
	}{proj, suffix}
	if err := xTemplate.Execute(w, data); err != nil {
		log.Println("xHandler:", err)
	}
}

var xTemplate = template.Must(template.New("x").Parse(`<!DOCTYPE html>
<html lang="en">
<title>The Go Programming Language</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="go-import" content="golang.org/x/{{.Proj}} git https://go.googlesource.com/{{.Proj}}">
<meta http-equiv="refresh" content="0; url=https://pkg.go.dev/golang.org/x/{{.Proj}}{{.Suffix}}">
</head>
<body>
<a href="https://pkg.go.dev/golang.org/x/{{.Proj}}{{.Suffix}}">Redirecting to documentation...</a>
</body>
</html>
`))

func toolchainHandler(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path != "/toolchain" {
		// Shouldn't happen if handler is registered correctly.
		http.NotFound(w, r)
		return
	}
	w.Write(toolchainPage)
}

var toolchainPage = []byte(`<!DOCTYPE html>
<html lang="en">
<head>
<title>The Go Programming Language</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="go-import" content="golang.org/toolchain mod https://go.dev/dl/mod">
<meta http-equiv="refresh" content="0; url=https://go.dev/dl/">
</head>
<body>
golang.org/toolchain is the module form of the Go toolchain releases.
<a href="https://go.dev/dl/">Redirecting to Go toolchain download page...</a>
</body>
</html>
`)

var _ fs.ReadDirFS = unionFS{}

// A unionFS is an FS presenting the union of the file systems in the slice.
// If multiple file systems provide a particular file, Open uses the FS listed earlier in the slice.
// If multiple file systems provide a particular directory, ReadDir presents the
// concatenation of all the directories listed in the slice (with duplicates removed).
type unionFS []fs.FS

func (fsys unionFS) Open(name string) (fs.File, error) {
	var errOut error
	for _, sub := range fsys {
		f, err := sub.Open(name)
		if err == nil {
			// Note: Should technically check for directory
			// and return a synthetic directory that merges
			// reads from all the matching directories,
			// but all the directory reads in internal/godoc
			// come from fsys.ReadDir, which does that for us.
			// So we can ignore direct f.ReadDir calls.
			return f, nil
		}
		if errOut == nil {
			errOut = err
		}
	}
	return nil, errOut
}

func (fsys unionFS) ReadDir(name string) ([]fs.DirEntry, error) {
	var all []fs.DirEntry
	var seen map[string]bool // seen[name] is true if name is listed in all; lazily initialized
	var errOut error
	for _, sub := range fsys {
		list, err := fs.ReadDir(sub, name)
		if err != nil {
			errOut = err
		}
		if len(all) == 0 {
			all = append(all, list...)
		} else {
			if seen == nil {
				// Initialize seen only after we get two different directory listings.
				seen = make(map[string]bool)
				for _, d := range all {
					seen[d.Name()] = true
				}
			}
			for _, d := range list {
				name := d.Name()
				if !seen[name] {
					seen[name] = true
					all = append(all, d)
				}
			}
		}
	}
	if len(all) > 0 {
		return all, nil
	}
	return nil, errOut
}

// A fixSpecsFS is an FS mapping /ref/mem.html and /ref/spec.html to
// /doc/go_mem.html and /doc/go_spec.html.
var _ fs.FS = &fixSpecsFS{}

type fixSpecsFS struct {
	fs fs.FS
}

func (fsys fixSpecsFS) Open(name string) (fs.File, error) {
	switch name {
	case "ref/mem.html", "ref/spec.html":
		if f, err := fsys.fs.Open(name); err == nil {
			// Let Go distribution win if they move.
			return f, nil
		}
		// Otherwise fall back to doc/go_*.html
		name = "doc/go_" + strings.TrimPrefix(name, "ref/")
		return fsys.fs.Open(name)

	case "doc/go_mem.html", "doc/go_spec.html":
		data := []byte("<!--{\n\t\"Redirect\": \"/ref/" + strings.TrimPrefix(strings.TrimSuffix(name, ".html"), "doc/go_") + "\"\n}-->\n")
		return &memFile{path.Base(name), bytes.NewReader(data)}, nil
	}

	return fsys.fs.Open(name)
}

// A hideRootMDFS is an FS that hides *.md files in the root directory.
// We use this to hide the Go repository's CONTRIBUTING.md,
// README.md, and SECURITY.md. The last is particularly problematic
// when running locally on a Mac, because it can be opened as
// security.md, which takes priority over _content/security.html.
// Same for wiki.
type hideRootMDFS struct {
	fs fs.FS
}

func (fsys hideRootMDFS) Open(name string) (fs.File, error) {
	if !strings.Contains(name, "/") && strings.HasSuffix(name, ".md") {
		return nil, errors.New(".md file not available")
	}
	switch name {
	case "wiki/README.md", "wiki/CONTRIBUTING.md", "wiki/LICENSE", "wiki/PATENTS", "wiki/codereview.cfg":
		return nil, errors.New("wiki meta file not available")
	}
	return fsys.fs.Open(name)
}

// A seekableFS is an FS wrapper that makes every file seekable
// by reading it entirely into memory when it is opened and then
// serving read operations (including seek) from the memory copy.
type seekableFS struct {
	fs fs.FS
}

func (s *seekableFS) Open(name string) (fs.File, error) {
	f, err := s.fs.Open(name)
	if err != nil {
		return nil, err
	}
	info, err := f.Stat()
	if err != nil {
		f.Close()
		return nil, err
	}
	if info.IsDir() {
		return f, nil
	}
	data, err := io.ReadAll(f)
	if err != nil {
		f.Close()
		return nil, err
	}
	var sf seekableFile
	sf.File = f
	sf.Reset(data)
	return &sf, nil
}

// A seekableFile is a fs.File augmented by an in-memory copy of the file data to allow use of Seek.
type seekableFile struct {
	bytes.Reader
	fs.File
}

// Read calls f.Reader.Read.
// Both f.Reader and f.File have Read methods - a conflict - so f inherits neither.
// This method calls the one we want.
func (f *seekableFile) Read(b []byte) (int, error) {
	return f.Reader.Read(b)
}

// A memFile is an fs.File implementation backed by in-memory data.
type memFile struct {
	name string
	*bytes.Reader
}

func (f *memFile) Stat() (fs.FileInfo, error) { return f, nil }
func (f *memFile) Name() string               { return f.name }
func (*memFile) Mode() fs.FileMode            { return 0o444 }
func (*memFile) ModTime() time.Time           { return time.Time{} }
func (*memFile) IsDir() bool                  { return false }
func (*memFile) Sys() interface{}             { return nil }
func (*memFile) Close() error                 { return nil }

// An atomicFS is an fs.FS value safe for reading from multiple goroutines
// as well as updating (assigning a different fs.FS to use in future read requests).
type atomicFS struct {
	v atomic.Value
}

// Set sets the file system used by future calls to Open.
func (a *atomicFS) Set(fsys fs.FS) {
	a.v.Store(&fsys)
}

// A mountFS is a root FS with a second FS mounted at a specific location.
type mountFS struct {
	old fs.FS  // root file system
	dir string // mount point
	new fs.FS  // fs mounted on dir
}

func (m *mountFS) Open(name string) (fs.File, error) {
	if name == m.dir {
		return m.new.Open(".")
	}
	if strings.HasPrefix(name, m.dir) && len(name) > len(m.dir) && name[len(m.dir)] == '/' {
		return m.new.Open(name[len(m.dir)+1:])
	}
	return m.old.Open(name)
}

var errNoFileSystem = errors.New("no file system")

// Open returns fsys.Open(name) where fsys is the file system passed to the most recent call to Set.
// If there has been no call to Set, Open returns errNoFileSystem, an error with text “no file system”.
func (a *atomicFS) Open(name string) (fs.File, error) {
	fsys, _ := a.v.Load().(*fs.FS)
	if fsys == nil {
		return nil, &fs.PathError{Path: name, Op: "open", Err: errNoFileSystem}
	}
	return (*fsys).Open(name)
}

func redirectPrefix(prefix string) http.Handler {
	return redirectPrefixQuery(prefix, "")
}

func redirectPrefixQuery(prefix, query string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		url := strings.TrimSuffix(prefix, "/") + "/" + strings.TrimPrefix(r.URL.Path, "/")
		if r.URL.RawQuery != "" || query != "" {
			url += "?"
			if r.URL.RawQuery != "" {
				url += r.URL.RawQuery
				if query != "" {
					url += "&"
				}
			}
			url += query
		}
		http.Redirect(w, r, url, http.StatusMovedPermanently)
	})
}

type CachedURL struct {
	url     string
	timeout time.Duration

	mu      sync.Mutex
	data    []byte
	err     error
	etag    string
	updated time.Time
}

func NewCachedURL(url string, timeout time.Duration) *CachedURL {
	return &CachedURL{url: url, timeout: timeout}
}

func (c *CachedURL) Get() (data []byte, err error) {
	c.mu.Lock()
	defer c.mu.Unlock()

	if time.Since(c.updated) < c.timeout {
		return c.data, c.err
	}
	defer func() {
		c.updated = time.Now()
		c.data, c.err = data, err
	}()

	cli := &http.Client{Timeout: 60 * time.Second}
	req, err := http.NewRequest("GET", c.url, nil)
	if err != nil {
		return nil, err
	}
	if c.etag != "" {
		req.Header.Set("If-None-Match", c.etag)
	}
	resp, err := cli.Do(req)
	if err != nil {
		return nil, fmt.Errorf("loading rebuild report JSON: %v", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode == http.StatusNotModified {
		// Unmodified.
		log.Printf("checked %s - unmodified", c.url)
		return c.data, c.err
	}
	log.Printf("reloading %s", c.url)
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("loading rebuild report JSON: %v", resp.Status)
	}
	c.etag = resp.Header.Get("Etag")
	data, err = io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("loading rebuild report JSON: %v", err)
	}
	return data, nil
}

func jsonUnmarshal(data []byte) (any, error) {
	var x any
	err := json.Unmarshal(data, &x)
	return x, err
}
