package core

import (
	"net/http"
)

type Response struct {
	http.ResponseWriter
	Status int
	Size   int
}

func NewResponse(w http.ResponseWriter) *Response {
	return &Response{
		ResponseWriter: w,
		Status:         200,
		Size:           0,
	}
}

func (r *Response) Header() http.Header {
	return r.ResponseWriter.Header()
}

func (r *Response) WriteHeader(status int) {
	r.Status = status
}

func (r *Response) WriteError(err *HTTPError) {
	r.Header().Set("Content-Type", "application/json")
	r.WriteHeader(err.Code)
	r.Write(err.IntoJsonBytes())
}

func (r *Response) Json(json []byte) {
	r.Header().Set("Content-Type", "application/json")
	r.Write(json)
}

func (r *Response) Write(b []byte) (int, error) {
	r.ResponseWriter.WriteHeader(r.Status)
	n, err := r.ResponseWriter.Write(b)
	r.Size += n

	return n, err
}

// Implement http.Handler
type ServerMux struct {
	mux *http.ServeMux
}

func NewServerMux() *ServerMux {
	return &ServerMux{
		mux: http.NewServeMux(),
	}
}

func (s *ServerMux) HandleFunc(pattern string, handler func(w *Response, r *http.Request)) {
	s.mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
		response := NewResponse(w)

		LogMiddleware(ErrorMiddleware(handler))(response, r)
	})
}

func (s *ServerMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.mux.ServeHTTP(w, r)
}