package global

import (
	"fmt"
	"math/rand"
	"net/http"
	"strconv"
	"time"

	"arimelody-web/colour"
)

var PoweredByStrings = []string{
    "nerd rage",
    "estrogen",
    "your mother",
    "awesome powers beyond comprehension",
    "jared",
    "the weight of my sins",
    "the arc reactor",
    "AA batteries",
    "15 euro solar panel from ebay",
    "magnets, how do they work",
    "a fax machine",
    "dell optiplex",
    "a trans girl's nintendo wii",
    "BASS",
    "electricity, duh",
    "seven hamsters in a big wheel",
    "girls",
    "mzungu hosting",
    "golang",
    "the state of the world right now",
    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)",
    "the good folks at aperture science",
    "free2play CDs",
    "aridoodle",
    "the love of creating",
    "not for the sake of art; not for the sake of money; we like painting naked people",
    "30 billion dollars in VC funding",
}

func DefaultHeaders(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Add("Server", "arimelody.me")
        w.Header().Add("Do-Not-Stab", "1")
        w.Header().Add("X-Clacks-Overhead", "GNU Terry Pratchett")
        w.Header().Add("X-Hacker", "spare me please")
        w.Header().Add("X-Robots-TXT", "'; DROP TABLE pages;")
        w.Header().Add("X-Thinking-With", "Portals")
        w.Header().Add(
            "X-Powered-By",
            PoweredByStrings[rand.Intn(len(PoweredByStrings))],
        )
        next.ServeHTTP(w, r)
    })
}

type LoggingResponseWriter struct {
    http.ResponseWriter
    Code int
}

func (lrw *LoggingResponseWriter) WriteHeader(code int) {
    lrw.Code = code
    lrw.ResponseWriter.WriteHeader(code)
}

func HTTPLog(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()

        lrw := LoggingResponseWriter{w, http.StatusOK}

        next.ServeHTTP(&lrw, r)

        after := time.Now()
        difference := (after.Nanosecond() - start.Nanosecond()) / 1_000_000
        elapsed := "<1"
        if difference >= 1 {
            elapsed = strconv.Itoa(difference)
        }

        codeColour := colour.Reset

        if lrw.Code - 600 <= 0 { codeColour = colour.Red }
        if lrw.Code - 500 <= 0 { codeColour = colour.Yellow }
        if lrw.Code - 400 <= 0 { codeColour = colour.White }
        if lrw.Code - 300 <= 0 { codeColour = colour.Green }

        fmt.Printf("[%s] %s %s - %s%d%s (%sms) (%s)\n",
        after.Format(time.UnixDate),
        r.Method,
        r.URL.Path,
        codeColour,
        lrw.Code,
        colour.Reset,
        elapsed,
        r.Header["User-Agent"][0])
    })
}

