package webServer

import (
	config "common/configsYaml"
	"common/resultStatus"
	"common/utils"
	"encoding/json"
	"fmt"
	"framework/ipMgr"
	"goutil/logUtilPlus"
	"goutil/stringUtil"
	"goutil/webUtil"
	"net/http"
	"strings"
)

// selfDefineMux
//
//	@description: 定义自定义的Mux对象
type selfDefineMux struct {
}

// ServeHTTP
//
//	@description: ServeHTTP
//
// parameter:
//
//	@receiver mux: mux
//	@w: w
//	@r: r
//
// return:
func (mux *selfDefineMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	responseObj := GetInitResponseObj()
	defer utils.LogReqErrorRecover(r)

	// 判断是否是接口文档
	if strings.Contains(r.RequestURI, "Remarks") && r.Method == "GET" {
		remarkFunc(w, r)
		return
	}

	// 判断是否是POST方法
	if r.Method != "POST" {
		responseResult(w, responseObj.SetResultStatus(resultStatus.OnlySupportPOST))
		return
	}

	// 验证IP是否正确
	if config.DEBUG == false && ipMgr.IsIpValid(webUtil.GetRequestIP(r)) == false {
		logUtilPlus.ErrorLog(fmt.Sprintf("请求的IP：%s无效", webUtil.GetRequestIP(r)))
		responseResult(w, responseObj.SetResultStatus(resultStatus.IPForbid))
		return
	}

	// 构造contex
	context, errMsg := NewApiContext(r, w, false)
	if errMsg != nil {
		// 输出结果
		responseResult(w, responseObj.SetResultStatus(resultStatus.APIDataError))
		return
	}

	// 根据路径选择不同的处理方法
	if handlerFunObj, exists := GetHandleFunc(r.RequestURI); exists {
		defer func() {
			if config.DEBUG {
				b, _ := json.Marshal(responseObj)
				msg := fmt.Sprintf("API:%v 请求数据：%v;返回数据：%s;",
					r.RequestURI, string(context.GetRequestBytes()), string(b))
				logUtilPlus.DebugLog(msg)
			}
		}()

		// 输出结果
		responseObj := handlerFunObj.HandleFun()(context)
		responseResult(w, responseObj)
		return
	}

	// 通过反射选择不同的方法
	strs := stringUtil.Split(r.RequestURI, []string{"/"})
	var params []interface{}
	var err error
	isJson := false

	// 参数错误
	if len(strs) != 2 {
		responseResult(w, responseObj.SetResultStatus(resultStatus.APIDataError))
		return
	}

	params, err = context.RequestDataBySlice2ByJson()
	if err != nil {
		responseResult(w, responseObj.SetResultStatus(resultStatus.APIDataError))
		return
	}

	//验证是否登录
	if !IsSkipVerifyTokenPage(strs[0], strs[1]) {
		tokenStr := context.header.Get("token")

		// token 转型成 int64
		token := stringUtil.StringToInt64(tokenStr)

		//是否存在
		exist, tokenData := CheckToken(token)
		if !exist {
			responseResult(w, responseObj.SetResultStatus(resultStatus.NotLogin))
			return
		}

		//添加登录用户到参数里的第一个
		params = append([]interface{}{tokenData.UserInfo}, params...)
	}

	//是否需要请求信息
	if IsNeedGetRequestInfo(strs[0], strs[1]) {

		//添加请求信息到最后一个参数
		params = append(params, r)
	}

	resquestData := NewRequestObject(strs[0], strs[1], params)
	resp := CallFunction(resquestData)
	if isJson {
		responseResultByJson(w, resp)
	} else {
		responseResult(w, resp)
	}

}
