package casbins

import (
	"LAPP_LF_MOM_BACKEND/conf"
	"LAPP_LF_MOM_BACKEND/web/middleware/glog"
	"LAPP_LF_MOM_BACKEND/web/middleware/jwts"
	"LAPP_LF_MOM_BACKEND/web/supports"
	"fmt"
	"github.com/casbin/casbin/v2"
	xormadapter "github.com/casbin/xorm-adapter/v2"
	_ "github.com/denisenkom/go-mssqldb"
	"github.com/kataras/iris/v12"
	"log"
	"net/http"
	"strings"
)

// 获取Enforcer
func NewCasbin() (*casbin.Enforcer, error) {

	driveSource := fmt.Sprintf("server=%s;database=%s;user id=%s;password=%s;port=%d;encrypt=disable",
		conf.DbConfig.Masterdbserver, conf.DbConfig.Masterdbname, conf.DbConfig.Masterdbuser, conf.DbConfig.Masterdbpassword, conf.DbConfig.Masterdbport)
	a, err := xormadapter.NewAdapter(conf.DbConfig.Masterdbdrivername, driveSource, true)
	if err != nil {
		glog.InfoExtln("casbins数据库连接错误", "err:", err)
		return nil, err
	}

	e, err := casbin.NewEnforcer("conf/rbac_model.conf", a)
	if err != nil {
		return nil, err
	}
	if err := e.LoadPolicy(); err == nil {
		return e, err
	} else {
		fmt.Printf("casbin rbac_model or policy init error, message: %v", err)
		return nil, err
	}
}

// ServeHTTP is the iris compatible casbins handler which should be passed to specific routes or parties.
// Usage:
// [...]
// app.Get("/dataset1/resource1", casbinMiddleware.ServeHTTP, myHandler)
// [...]
func CheckPermissions(ctx iris.Context) bool {
	user, ok := jwts.ParseToken(ctx)
	if !ok {
		return false
	}

	// 去除空格
	//uid := strings.Replace(user.Userid, " ", "", -1)
	uid := strings.TrimSpace(user.Role)
	e, err := NewCasbin()
	if err != nil {
		supports.Unauthorized(ctx, supports.PermissionsLess, nil)
		ctx.StopExecution()
		return false
	}
	ok, err = e.Enforce(uid, ctx.Path(), ctx.Method())
	log.Println("----------------", uid, ctx.Path(), ctx.Method())
	log.Println(ok)
	if err != nil {
		log.Printf("casbin权限控制错误: %v", err)
	}
	if !ok {
		supports.Unauthorized(ctx, supports.PermissionsLess, nil)
		ctx.StopExecution()
		return false
	}

	return true
	//ctx.Next()
}

// Wrapper is the router wrapper, prefer this method if you want to use casbins to your entire iris application.
// Usage:
// [...]
// app.WrapRouter(casbinMiddleware.Wrapper())
// app.Get("/dataset1/resource1", myHandler)
// [...]
func Wrapper() func(w http.ResponseWriter, r *http.Request, router http.HandlerFunc) {
	return func(w http.ResponseWriter, r *http.Request, router http.HandlerFunc) {
		//if !c.Check(r) {
		//	w.WriteHeader(http.StatusForbidden)
		//	w.Write([]byte("403 Forbidden"))
		//	return
		//}
		router(w, r)
	}
}
