package pairec

import (
	"fmt"
	"io"
	"net/http"
	"runtime/debug"
	"strings"

	"gitlab.alibaba-inc.com/pai_biz_arch/pairec/log"
)

type ControllerInterface interface {
	Process(http.ResponseWriter, *http.Request)
}
type ControllerRegister struct {
	routeInfos map[string]*RouteInfo
}

func NewControllerRegister() *ControllerRegister {
	cr := &ControllerRegister{
		routeInfos: make(map[string]*RouteInfo),
	}
	return cr
}

func (c *ControllerRegister) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	defer func() {
		if err := recover(); err != nil {
			stack := string(debug.Stack())
			log.Error(fmt.Sprintf("error=%v, stack=%s", err, strings.ReplaceAll(stack, "\n", "\t")))
			Error(rw, 500, "server error")
		}
	}()

	uri := req.RequestURI

	if index := strings.Index(req.RequestURI, "?"); index != -1 {
		uri = req.RequestURI[:index]
	}

	if info, exist := c.routeInfos[uri]; exist {

		if info.initialize != nil {
			c := info.initialize()
			c.Process(rw, req)
		} else if info.hf != nil {
			info.hf(rw, req)
		} else {
			// return 404
			Error(rw, 404, "controller not found")
			return
		}

	} else {
		// return 404
		Error(rw, 404, "url not found route info")
		return
	}
}

func (c *ControllerRegister) Register(routeInfo *RouteInfo) {
	c.routeInfos[routeInfo.pattern] = routeInfo
}
func Error(rw http.ResponseWriter, code int, msg string) {
	rw.WriteHeader(code)
	io.WriteString(rw, msg)
}
