// Package router ...
//
// Description : router ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-11-01 12:34
package router

import (
	"git.zhangdeman.cn/zhangdeman/consts"
	"git.zhangdeman.cn/zhangdeman/gin/define"
	"git.zhangdeman.cn/zhangdeman/gin/logger"
	"git.zhangdeman.cn/zhangdeman/gin/util"
	pkgLogger "git.zhangdeman.cn/zhangdeman/logger"
	"github.com/gin-gonic/gin"
)

// hook 执行hook逻辑
func (s *server) hook(ctx *gin.Context, uriCfg define.UriConfig) {
	var (
		exists        bool
		isSuccess     any
		responseAfter any
	)

	innerContext := util.GinCtxToContext(ctx)
	if responseAfter, exists = ctx.Get(consts.GinLogicAfterResponseKey); !exists || nil == responseAfter {
		// 未配置
		logger.Instance.Debug("未配置 Logic 执行后的 hook 逻辑", pkgLogger.NewLogData(innerContext, logger.RecordType, logger.CodeLogicHook, map[string]any{
			"uri":                      uriCfg.Path,
			"logic_after_response_key": consts.GinLogicAfterResponseKey,
		}).ToFieldList()...)
		return
	}
	success := false
	if isSuccess, exists = ctx.Get(consts.GinRequestSuccess); exists && nil != isSuccess && (isSuccess == "1" || isSuccess == "true" || isSuccess.(bool)) {
		success = true
	}
	hookInstance := responseAfter.(*define.LogicAfterResponse)
	if uriCfg.HookSync {
		// 同步执行
		s.hookAfter(ctx, uriCfg, hookInstance, success)
	} else {
		// 异步执行
		go s.hookAfter(util.Copy(ctx), uriCfg, hookInstance, success)
	}
}

func (s *server) hookAfter(ctx *gin.Context, uriCfg define.UriConfig, hookInstance *define.LogicAfterResponse, success bool) {
	innerContext := util.GinCtxToContext(ctx)
	defer func() {
		if err := recover(); err != nil {
			logger.Instance.Error("hook 执行异常", pkgLogger.NewLogData(innerContext, logger.RecordType, logger.CodeLogicHook, map[string]any{
				"uri":                      uriCfg.Path,
				"logic_after_response_key": consts.GinLogicAfterResponseKey,
				"error":                    err.(error).Error(),
				"logic_success":            success,
			}).ToFieldList()...)
		}
	}()
	if success {
		logger.Instance.Debug("接口Logic执行成功, 执行Hook逻辑", pkgLogger.NewLogData(innerContext, logger.RecordType, logger.CodeLogicHook, map[string]any{}).ToFieldList()...)
		for _, itemFunc := range hookInstance.SuccessHookFuncList {
			if nil != itemFunc {
				itemFunc(ctx)
			}
		}
	} else {
		logger.Instance.Debug("接口Logic执行失败, 执行Hook逻辑", pkgLogger.NewLogData(innerContext, logger.RecordType, logger.CodeLogicHook, map[string]any{}).ToFieldList()...)
		for _, itemFunc := range hookInstance.FailureHookFuncList {
			if nil != itemFunc {
				itemFunc(ctx)
			}
		}
	}
}
