package main

import (
	"context"
	_ "embed"
	"fmt"
	"net/http"
	"os"
)

type Context struct {
	User string
}

func HTTP(port int, db DB) error {
	foo := func(w http.ResponseWriter, r *http.Request) {
		switch r.URL.Path {
		case "/":
			httpRoot(w, r)
		default:
			http.NotFound(w, r)
		}
	}
	foo = withAuth(foo)
	return http.ListenAndServe(fmt.Sprintf(":%d", port), http.HandlerFunc(foo))
}

func extract(ctx context.Context) Context {
	v := ctx.Value("__context")
	v2, _ := v.(Context)
	return v2
}

func inject(ctx context.Context, v Context) context.Context {
	return context.WithValue(ctx, "__context", v)
}

func withAuth(foo http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		u, _, ok := r.BasicAuth()
		if !ok || u == "" {
			w.Header().Set("WWW-Authenticate", "Basic")
			w.WriteHeader(401)
			return
		}
		c := extract(r.Context())
		c.User = u
		r = r.WithContext(inject(r.Context(), c))
		foo(w, r)
	}
}

//go:embed public/root.html
var httpRootHTML string

func httpRoot(w http.ResponseWriter, r *http.Request) {
	body := httpRootHTML
	if os.Getenv("DEBUG") {
		b, _ := os.ReadFile("public/root.html")
		body = string(b)
	}
	w.Write([]byte(body))
}
