package middleware

import (
	"net/http"
	"strings"

	"git.kirsle.net/apps/gophertype/pkg/responses"
	"git.kirsle.net/apps/gophertype/pkg/session"
	"git.kirsle.net/apps/gophertype/pkg/settings"
)

// URL suffixes to allow to bypass the age gate middleware.
var ageGateSuffixes = []string{
	"/blog.rss", // Allow public access to RSS and Atom feeds.
	"/blog.atom",
	"/blog.json",
	".js",
	".css",
	".txt",
	".ico",
	".png",
	".jpg",
	".jpeg",
	".gif",
	".mp4",
	".webm",
	".ttf",
	".eot",
	".svg",
	".woff",
	".woff2",
}

// AgeGate is a middleware generator that does age verification for NSFW sites.
// Single GET requests with ?over18=1 parameter may skip the middleware check.
func AgeGate(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		s := settings.Current
		if !s.NSFW {
			next.ServeHTTP(w, r)
			return
		}

		path := r.URL.Path

		// Let the age-verify handler catch its route.
		if strings.HasPrefix(path, "/age-verify") {
			next.ServeHTTP(w, r)
			return
		}

		// Allow static file requests to skip the check.
		for _, suffix := range ageGateSuffixes {
			if strings.HasSuffix(path, suffix) {
				next.ServeHTTP(w, r)
				return
			}
		}

		// POST requests are permitted (e.g. post a comment on a /?over18=1 page)
		if r.Method == http.MethodPost {
			next.ServeHTTP(w, r)
			return
		}

		// Finally, check if they've confirmed their age on the age-verify handler.
		ses := session.Get(r)
		if !ses.AgeOK {
			// They haven't been verified. Redirect them to the age-verify handler.
			if r.FormValue("over18") == "" && r.Header.Get("X-Over-18") == "" {
				responses.Redirect(w, r, "/age-verify?next="+path)
				return
			}
		}

		next.ServeHTTP(w, r)
	})
}
