package mux

import (
	"net/http"
	"path/filepath"
	"strings"
	
	"github.com/gorilla/mux"
)

type (
	MiddlewareFunc = mux.MiddlewareFunc
	Router         = mux.Router
)

var (
	defaultRouter  = mux.NewRouter()
	defaultMethods = []string{http.MethodGet, http.MethodPost}
)

func New() *mux.Router {
	return mux.NewRouter()
}

func RegisterWith(router *mux.Router, path string, handler http.HandlerFunc, methods ...string) {
	r := router.HandleFunc(path, handler)
	if len(methods) == 0 {
		methods = defaultMethods
	}
	r.Methods(methods...)
}

type GroupMux struct {
	router *mux.Router
}

func (g *GroupMux) Register(path string, handler http.HandlerFunc, methods ...string) {
	r := g.router.Handle(path, handler)
	if len(methods) == 0 {
		methods = defaultMethods
	}
	r.Methods(methods...)
}

func (g *GroupMux) RegisterHandle(path string, handler http.Handler, methods ...string) {
	g.Register(path, handler.ServeHTTP, methods...)
}

func (g *GroupMux) Use(mwf ...mux.MiddlewareFunc) {
	g.router.Use(mwf...)
}

func GroupWith(router *Router, prefix string) *GroupMux {
	return &GroupMux{router: router.PathPrefix(prefix).Subrouter()}
}

func Default() *mux.Router {
	return defaultRouter
}

func Register(path string, handler http.HandlerFunc, methods ...string) {
	RegisterWith(defaultRouter, path, handler, methods...)
}

func RegisterHandle(path string, handler http.Handler, methods ...string) {
	Register(path, handler.ServeHTTP, methods...)
}

func Group(prefix string) *GroupMux {
	return GroupWith(defaultRouter, prefix)
}

func Use(handle mux.MiddlewareFunc) {
	defaultRouter.Use(handle)
}

func Params(r *http.Request) map[string]string {
	return mux.Vars(r)
}

func SetStaticPath(router *mux.Router, path, dir string) {
	if strings.LastIndex(path, "/") == -1 {
		path = path + "/"
	}
	router.PathPrefix(path).Handler(http.StripPrefix(path, http.FileServer(http.Dir(filepath.Join(dir)))))
}

func CORS() mux.MiddlewareFunc {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
			w.Header().Add("Access-Control-Allow-Origin", "*")
			w.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
			w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
			w.Header().Add("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
			w.Header().Add("Access-Control-Allow-Credentials", "true")
			next.ServeHTTP(w, req)
		})
	}
}
