package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log/slog"
	"net"
	"net/http"
	"time"
)

type RFCTime struct {
	DayOfWeek  string `json:"day_of_week"`
	DayOfMonth int    `json:"day_of_month"`
	Month      string `json:"month"`
	Year       int    `json:"year"`
	Hour       int    `json:"hour"`
	Minute     int    `json:"minute"`
	Second     int    `json:"second"`
}

type TimeHandler struct{}

func StructToJsString(data any) string {
	var b bytes.Buffer
	enc := json.NewEncoder(&b)
	err := enc.Encode(data)
	if err != nil {
		slog.Error("Problems with encoding json")
	}
	return b.String()
}

func (th TimeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	headerAccept := http.Header.Get(r.Header, "Accept")
	var output string
	switch headerAccept {
	case "application/json":
		currTime := time.Now()
		rfcTime := RFCTime{
			DayOfWeek:  currTime.Weekday().String(),
			DayOfMonth: currTime.Day(),
			Month:      currTime.Month().String(),
			Year:       currTime.Year(),
			Hour:       currTime.Hour(),
			Minute:     currTime.Minute(),
			Second:     currTime.Second(),
		}
		output = StructToJsString(rfcTime)
	default:
		output = time.Now().Format(time.RFC3339)
	}
	w.Write([]byte(output))
}

func RequestToIP(r *http.Request) string {
	ip, _, err := net.SplitHostPort(r.RemoteAddr)
	if err != nil {
		slog.Error(fmt.Sprintf("Wrong format of address: %q", r.RemoteAddr))
	}
	return ip
}

func RequestIPHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		slog.Info(RequestToIP(r))
		h.ServeHTTP(w, r)
	})
}

func main() {
	server := http.Server{
		Addr:         ":10100",
		ReadTimeout:  30 * time.Second,
		WriteTimeout: 90 * time.Second,
		IdleTimeout:  120 * time.Second,
		Handler:      RequestIPHandler(TimeHandler{}),
	}
	err := server.ListenAndServe()
	if err != nil {
		if err != http.ErrServerClosed {
			panic(err)
		}
	}
}
