package util

import (
	"net/http"
	"runtime"

	"git.chuangxin1.com/cx/util/httprouter"
)

// Router router
type Router = httprouter.Router

// Handle is a function that can be registered to a route to handle HTTP
// requests. Like http.HandlerFunc.
type Handle func(http.ResponseWriter, *http.Request)

// NewRouter new http router with default route
func NewRouter() *Router {
	router := httprouter.New()

	router.NotFound = http.HandlerFunc(notFoundHandler)
	router.PanicHandler = panicHandler
	router.MethodNotAllowed = http.HandlerFunc(notAllowedHandler)

	router.GET("/api/ver", defaultHandler)
	//router.GET("/api/health", defaultHandler)
	//router.Handler("GET", "/metrics", promhttp.Handler())

	return router
}

func defaultHandler(w http.ResponseWriter, r *http.Request) {
	ver := map[string]string{
		"version": LibVersion,
		"name":    LibName}
	WriteJSON(w, RowReplyData(ver))
}

func panicHandler(w http.ResponseWriter, r *http.Request, err interface{}) {
	e := err.(runtime.Error)

	WriteJSON(w, ErrReplyData(ErrException, e.Error()))
}

func notFoundHandler(w http.ResponseWriter, req *http.Request) {
	WriteJSON(w, ErrReplyData(ErrNotFound, `NotFound`))
}

func notAllowedHandler(w http.ResponseWriter, req *http.Request) {
	WriteJSON(w, ErrReplyData(ErrNotAllowed, `Method Not Allowed`))
}

// AddHandler add handler to router
func AddHandler(router *httprouter.Router, method, route string, handler http.Handler) {
	router.Handler(method, route, handler)
}

// AddGetHandle add handle to router
func AddGetHandle(router *httprouter.Router, route string, handle Handle) {
	router.GET(route, httprouter.Handle(handle))
}

// AddPostHandle add handle to router
func AddPostHandle(router *httprouter.Router, route string, handle Handle) {
	router.POST(route, httprouter.Handle(handle))
}

// AddPutHandle add handle to router
func AddPutHandle(router *httprouter.Router, route string, handle Handle) {
	router.PUT(route, httprouter.Handle(handle))
}

// AddHeadHandle add handle to router
func AddHeadHandle(router *httprouter.Router, route string, handle Handle) {
	router.HEAD(route, httprouter.Handle(handle))
}

// AddDeleteHandle add handle to router
func AddDeleteHandle(router *httprouter.Router, route string, handle Handle) {
	router.DELETE(route, httprouter.Handle(handle))
}

// AddPatchHandle add handle to router
func AddPatchHandle(router *httprouter.Router, route string, handle Handle) {
	router.PATCH(route, httprouter.Handle(handle))
}

// AddOptionsHandle add handle to router
func AddOptionsHandle(router *httprouter.Router, route string, handle Handle) {
	router.OPTIONS(route, httprouter.Handle(handle))
}