package gosh

import (
	"net/http"

	"git.kingecg.top/kingecg/gosh/interceptor"
	"github.com/mattn/anko/env"
)

const (
	GET   = "GET"
	POST  = "POST"
	PUT   = "PUT"
	DEL   = "DELETE"
	PATCH = "PATCH"
)

type SHMux struct {
	*http.ServeMux
	ankoEnv      *env.Env
	getScripts   map[string]string
	postScripts  map[string]string
	putScripts   map[string]string
	delScripts   map[string]string
	patchScripts map[string]string
}

func NewSHMux() *SHMux {
	s := &SHMux{
		ServeMux: http.NewServeMux(),
		ankoEnv:  env.NewEnv(),
	}
	//s.executor = interceptor.NewAnkointerceptor(s.ankoEnv)
	return s
}

func (s *SHMux) RegistFunction(name string, function interface{}) {
	if s.ankoEnv != nil {
		_ = s.ankoEnv.Define(name, function)
	}
}

func (s *SHMux) register(method, pattern, script string) {
	switch method {
	case GET:
		if s.getScripts == nil {
			s.getScripts = make(map[string]string)
		}
		s.getScripts[pattern] = script
	case POST:
		if s.postScripts == nil {
			s.postScripts = make(map[string]string)
		}
		s.postScripts[pattern] = script
	case PUT:
		if s.putScripts == nil {
			s.putScripts = make(map[string]string)
		}
		s.putScripts[pattern] = script
	case DEL:
		if s.delScripts == nil {
			s.delScripts = make(map[string]string)
		}
		s.delScripts[pattern] = script
	case PATCH:
		if s.patchScripts == nil {
			s.patchScripts = make(map[string]string)
		}
		s.patchScripts[pattern] = script
	}
}
func (s *SHMux) GET(pattern, script string) {
	s.register(GET, pattern, script)
}
func (s *SHMux) POST(pattern, script string) {
	s.register(POST, pattern, script)
}
func (s *SHMux) PUT(pattern, script string) {
	s.register(PUT, pattern, script)
}
func (s *SHMux) DELETE(pattern, script string) {
	s.register(DEL, pattern, script)
}
func (s *SHMux) PATCH(pattern, script string) {
	s.register(PATCH, pattern, script)
}

func (s *SHMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	var script string
	switch r.Method {
	case GET:
		script = s.getScripts[r.URL.Path]
	case POST:
		script = s.postScripts[r.URL.Path]
	case PUT:
		script = s.putScripts[r.URL.Path]
	case DEL:
		script = s.delScripts[r.URL.Path]
	case PATCH:
		script = s.patchScripts[r.URL.Path]
	}
	s.handle(w, r, script)
}

func (s *SHMux) handle(w http.ResponseWriter, r *http.Request, script string) {
	if script == "" {
		http.NotFound(w, r)
		return
	}
	reqHelper := &RequestHelper{
		r: r,
	}
	resHelper := &ResponseHelper{
		w: w,
	}
	renv := s.ankoEnv.Copy()
	_ = renv.Define("Req", reqHelper)
	_ = renv.Define("Res", resHelper)
	rinterceptor := interceptor.NewAnkointerceptor(renv)

	_, err := rinterceptor.ExecContent(script)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	// w.Write([]byte(script))
}
