package middleware

import (
	"server/utility/ecode"
	"server/utility/jwt"
	"strings"

	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/glog"
)

// Auth 是用于权限验证的中间件。
//
// 它会从请求头中读取 Authorization 字段，验证 JWT Token 的合法性。
// 如果请求未携带 Token，则默认赋予 "guest" 权限。
// 如果 Token 存在且合法，则将用户信息（userId、permission、jti）注入到请求上下文中。
//
// Token 应采用 Bearer 方案，例如：
//
//	Authorization: Bearer <token>
//
// 参数:
//
//	r *ghttp.Request - 当前的请求对象，由 ghttp 框架自动注入。
//
// 行为:
//   - 若无 Token：设定 permission 为 guest，放行请求。
//   - 若 Token 格式非法或解析失败：终止请求并返回错误。
//   - 若 Token 合法：将用户信息写入上下文，继续执行下一个中间件或处理函数。
func Auth(r *ghttp.Request) {
	token := r.GetHeader("Authorization")
	ctx := r.GetCtx()
	if token == "" {
		glog.Infof(ctx, "未登录用户访问: %s %s", r.URL.Path, r.Method)
		r.SetCtxVar("role", "guest")
	} else {
		if !strings.HasPrefix(token, "Bearer ") {
			r.SetError(ecode.InvalidOperation.Sub("invalid_token_format"))
			return
		}
		tokenOut, err := jwt.ParseToken(token)
		if err != nil {
			r.SetError(err)
			return
		}
		r.SetCtxVar("id", tokenOut.UserId)
		r.SetCtxVar("role", tokenOut.Role)
		r.SetCtxVar("jti", tokenOut.JTI)
		glog.Infof(ctx, "%s用户Id:%d 访问: %s %s", tokenOut.Role, tokenOut.UserId, r.URL.Path, r.Method)
	}
	r.Middleware.Next()
}
