package server

import (
	"net/http"
	"strings"

	"github.com/samber/lo"
)

// 可以嵌套的Rest http server mux
type RestMux struct {
	Path      string
	imux      *http.ServeMux
	rmuxPaths []string
}

func (mux *RestMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	_, has := lo.Find[string](mux.rmuxPaths, func(s string) bool {
		return strings.HasPrefix(r.URL.Path, s)
	})
	if has {
		mux.imux.ServeHTTP(w, r)
		return
	}

	r.URL.Path = "/" + strings.ToLower(r.Method) + r.URL.Path
	r.RequestURI = "/" + strings.ToLower(r.Method) + r.RequestURI
	h, _ := mux.imux.Handler(r)

	h.ServeHTTP(w, r)
}

func (mux *RestMux) HandleFunc(method string, path string, f func(http.ResponseWriter, *http.Request)) {
	m := path
	if !strings.HasPrefix(path, "/") {
		m = "/" + path
	}
	mux.imux.HandleFunc("/"+strings.ToLower(method)+m, f)
}

func (mux *RestMux) Get(path string, f func(http.ResponseWriter, *http.Request)) {
	mux.HandleFunc("GET", path, f)
}

func (mux *RestMux) Post(path string, f func(http.ResponseWriter, *http.Request)) {
	mux.HandleFunc("POST", path, f)
}

func (mux *RestMux) Put(path string, f func(http.ResponseWriter, *http.Request)) {
	mux.HandleFunc("PUT", path, f)
}
func (mux *RestMux) Delete(path string, f func(http.ResponseWriter, *http.Request)) {
	mux.HandleFunc("DELETE", path, f)
}
func (mux *RestMux) Patch(path string, f func(http.ResponseWriter, *http.Request)) {
	mux.HandleFunc("PATCH", path, f)
}
func (mux *RestMux) Head(path string, f func(http.ResponseWriter, *http.Request)) {
	mux.HandleFunc("HEAD", path, f)
}

func (mux *RestMux) Option(path string, f func(http.ResponseWriter, *http.Request)) {
	mux.HandleFunc("OPTION", path, f)
}

func (mux *RestMux) HandleMux(nmux *RestMux) {
	p := nmux.Path
	if !strings.HasSuffix(p, "/") {
		p = p + "/"
	}
	mux.imux.Handle(p, http.StripPrefix(nmux.Path, nmux))
	mux.rmuxPaths = append(mux.rmuxPaths, nmux.Path)
}

func NewRestMux(path string) *RestMux {
	return &RestMux{
		Path:      path,
		imux:      http.NewServeMux(),
		rmuxPaths: make([]string, 0),
	}
}
