// 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 main

import (
	"log"
	"net"
	"net/http"
	"net/url"
	"os"
	"strings"

	"golang.org/x/go.dev/cmd/internal/site"
)

var discoveryHosts = map[string]string{
	"":               "pkg.go.dev",
	"dev.go.dev":     "dev-pkg.go.dev",
	"staging.go.dev": "staging-pkg.go.dev",
}

func main() {
	dir := "../.."
	if _, err := os.Stat("_content"); err == nil {
		// Running in repo root.
		dir = "."
	}
	godev, err := site.Load(dir)
	if err != nil {
		log.Fatal(err)
	}
	http.Handle("/", addCSP(http.FileServer(godev)))
	http.Handle("/explore/", http.StripPrefix("/explore/", redirectHosts(discoveryHosts)))
	http.Handle("learn.go.dev/", http.HandlerFunc(redirectLearn))

	addr := ":" + listenPort()
	if addr == ":0" {
		addr = "localhost:0"
	}
	l, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatalf("net.Listen(%q, %q) = _, %v", "tcp", addr, err)
	}
	defer l.Close()
	log.Printf("Listening on http://%v/\n", l.Addr().String())
	log.Print(http.Serve(l, nil))
}

func redirectLearn(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, "https://go.dev/learn/"+strings.TrimPrefix(r.URL.Path, "/"), http.StatusMovedPermanently)
}

func listenPort() string {
	if p := os.Getenv("PORT"); p != "" {
		return p
	}
	return "0"
}

type redirectHosts map[string]string

func (rh redirectHosts) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	u := &url.URL{Scheme: "https", Path: r.URL.Path, RawQuery: r.URL.RawQuery}
	if h, ok := rh[r.Host]; ok {
		u.Host = h
	} else if h, ok := rh[""]; ok {
		u.Host = h
	} else {
		http.NotFound(w, r)
		return
	}
	http.Redirect(w, r, u.String(), http.StatusFound)
}
