package main

import (
	"context"
	"fmt"
	"log"

	"github.com/tidbcloud/tiinf/sdk/rbac"

	"github.com/gin-gonic/gin"
	"github.com/tidbcloud/tiinf/sdk/rbac/common"
	"github.com/tidbcloud/tiinf/sdk/rbac/useadapter"
)

// access call: curl -H 'Authorization:12345' 'http://localhost:8080/test'

// Example_Use_GinPermissionCheckInterceptor example for use GinPermissionCheckInterceptor in gin framework
func Example_Use_GinPermissionCheckInterceptor() {
	eng := gin.Default()
	eng.Use(
		// add extract identity interceptor
		ginExtractIdentityInterceptor(),
		// add permission check interceptor
		useadapter.GinPermissionCheckInterceptorWithCommonParam(&rbac.PermissionCheckerCommonParam{
			IdentityF:               ginGetIdentityFunc,
			PathPattern2ResourceMap: pathPattern2ResourceMap,
			PathWhitelist:           pathWhitelist,
			ResourceCascadeF:        checkCascadeResource,
		}),
	)
	eng.GET("/test", ginBizLogic)
	eng.GET("/api/v1/orgs/:org_id/projects/:project_id/get", ginBizLogic)
	eng.Run("127.0.0.1:8080")
}

var ginIdentityKey = "example_gin_identity_key"

// extract user id logic
func ginExtractIdentityInterceptor() func(ctx *gin.Context) {
	return func(c *gin.Context) {
		header := c.Request.Header
		hs := header["Authorization"]
		if hs == nil || len(hs) == 0 {
			panic("not found Authorization")
		}
		c.Set(ginIdentityKey, hs[0])
		c.Next()
	}
}

// get identity logic
func ginGetIdentityFunc(ctx context.Context, param *common.AccessParam) (string, error) {
	c := param.Req.(*gin.Context)
	identity, _ := c.Get(ginIdentityKey)
	userID := identity.(string)
	return userID, nil
}

func checkCascadeResource(ctx context.Context, resourceUri string) (matched bool, msg string, err error) {
	resourceValue := common.ParseCascadeResourceValue(resourceUri, []string{"orgs", "projects", "clusters"})
	orgId := resourceValue["orgs"]
	projectId := resourceValue["projects"]
	if orgId == "1" && projectId == "2" {
		return true, "matched", nil
	}
	return false, fmt.Sprintf("orgs:%s not match projects:%s", orgId, projectId), nil
}

func ginBizLogic(c *gin.Context) {
	log.Println("### example gin ###, receive req: ", c.Request.RequestURI)
}
