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

// Require go1.25+ for http.CrossOriginProtection.
// (This can be deleted when go.mod is at 1.25.0+.)
//go:build go1.25

// The admingolangorg command serves an administrative interface for owners of
// the golang-org Google Cloud project.
package main

import (
	"context"
	_ "embed"
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"time"

	"cloud.google.com/go/datastore"
	"golang.org/x/website/internal/memcache"
	"golang.org/x/website/internal/short"
	"google.golang.org/api/idtoken"
)

//go:embed index.html
var index string

func main() {
	audience := os.Getenv("IAP_AUDIENCE")
	dsClient, mcClient := getClients()
	mux := http.NewServeMux()
	mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/html")
		w.Write([]byte(index))
	}))
	mux.Handle("/shortlink", short.AdminHandler(dsClient, mcClient))
	mux.Handle("/snippet", &snippetHandler{dsClient})
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
		log.Printf("Defaulting to port %s", port)
	}
	handler := iapAuth(audience, mux)
	handler = http.NewCrossOriginProtection().Handler(handler)

	log.Printf("Listening on port %s", port)
	log.Fatal(http.ListenAndServe(":"+port, handler))
}

type snippetHandler struct {
	ds *datastore.Client
}

//go:embed snippet.html
var snippetForm string

func (h *snippetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	snippetLink := r.FormValue("snippet")
	if snippetLink == "" {
		w.Header().Set("Content-Type", "text/html")
		w.Write([]byte(snippetForm))
		return
	}

	prefixes := []string{
		"https://play.golang.org/p/",
		"http://play.golang.org/p/",
		"https://go.dev/play/p/",
		"http://go.dev/play/p/",
	}
	var snippetID string
	for _, p := range prefixes {
		if id, ok := strings.CutPrefix(snippetLink, p); ok {
			snippetID = id
			break
		}
	}
	if !strings.Contains(snippetLink, "/") {
		snippetID = snippetLink
	}
	if snippetID == "" {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "must specify snippet URL or ID\n")
		return
	}

	k := datastore.NameKey("Snippet", snippetID, nil)
	if h.ds.Get(r.Context(), k, new(struct{})) == datastore.ErrNoSuchEntity {
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(w, "Snippet with ID %q does not exist\n", snippetID)
		return
	}
	if err := h.ds.Delete(r.Context(), k); err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, "Unable to delete Snippet with ID %q: %v\n", snippetID, err)
		return
	}
	w.Write([]byte("snippet deleted\n"))
}

func getClients() (*datastore.Client, *memcache.Client) {
	ctx := context.Background()

	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)

	return datastoreClient, memcacheClient
}

func iapAuth(audience string, h http.Handler) http.Handler {
	// https://cloud.google.com/iap/docs/signed-headers-howto#verifying_the_jwt_payload
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		jwt := r.Header.Get("x-goog-iap-jwt-assertion")
		if jwt == "" {
			w.WriteHeader(http.StatusUnauthorized)
			fmt.Fprintf(w, "must run under IAP\n")
			return
		}

		payload, err := idtoken.Validate(r.Context(), jwt, audience)
		if err != nil {
			w.WriteHeader(http.StatusUnauthorized)
			log.Printf("JWT validation error: %v", err)
			return
		}
		if payload.Issuer != "https://cloud.google.com/iap" {
			w.WriteHeader(http.StatusUnauthorized)
			log.Printf("Incorrect issuer: %q", payload.Issuer)
			return
		}
		if payload.Expires+30 < time.Now().Unix() || payload.IssuedAt-30 > time.Now().Unix() {
			w.WriteHeader(http.StatusUnauthorized)
			log.Printf("Bad JWT times: expires %v, issued %v", time.Unix(payload.Expires, 0), time.Unix(payload.IssuedAt, 0))
			return
		}
		h.ServeHTTP(w, r)
	})
}
