package common

import "context"

// --------- handler -------------------

type AccessDecisionHandler interface {
	Handle(ctx context.Context, param *AccessParam) (*AccessResult, error)
}

type AccessParam struct {
	Metadata map[string]interface{}
	Req      interface{}
}

type AccessResult struct {
	Code int32
	Msg  string
	Data interface{}
}

type ResourceCascadeParam struct {
	ResourceUri string // orgs/1/projects/2/clusters/3/update
}

type ResourceCascadeResult struct {
	Matched bool
	Msg     string
}

// ------ helper ---------------

type IdentityHelper interface {
	GetIdentity(ctx context.Context, param *AccessParam) (string, error)
}

type ResourceHelper interface {
	GetResource(ctx context.Context, param *AccessParam) (string, error)
}

type RegionResourceHelper interface {
	GetResourceAndAppID(ctx context.Context, param *AccessParam) (string, string, error)
}

type PermissionHelper interface {
	HasPermission(ctx context.Context, identity, resource string) (bool, error)
}

type RegionPermissionHelper interface {
	HasPermission(ctx context.Context, identity, resource, appID string) (bool, error)
}

type RequestHelper interface {
	ReleaseRequest(ctx context.Context, param *AccessParam) (bool, error)
}

type ResourceCascadeChecker interface {
	CheckCascadeResource(ctx context.Context, param *ResourceCascadeParam) (*ResourceCascadeResult, error)
}

// ------ helper func ---------------

type GetIdentityFunc func(ctx context.Context, param *AccessParam) (string, error)

func (f GetIdentityFunc) GetIdentity(ctx context.Context, param *AccessParam) (string, error) {
	return f(ctx, param)
}

type GetResourceFunc func(ctx context.Context, param *AccessParam) (string, error)

func (f GetResourceFunc) GetResource(ctx context.Context, param *AccessParam) (string, error) {
	return f(ctx, param)
}

type ReleaseRequestFunc func(ctx context.Context, param *AccessParam) (bool, error)

func (f ReleaseRequestFunc) ReleaseRequest(ctx context.Context, param *AccessParam) (bool, error) {
	return f(ctx, param)
}

type CheckCascadeResourceFunc func(ctx context.Context, resourceUri string) (matched bool, msg string, err error)

func (f CheckCascadeResourceFunc) CheckCascadeResource(ctx context.Context, param *ResourceCascadeParam) (*ResourceCascadeResult, error) {
	if f == nil {
		ret := ResourceCascadeResult{
			Matched: true,
			Msg:     "not set CheckCascadeResourceFunc",
		}
		return &ret, nil
	}
	matched, msg, err := f(ctx, param.ResourceUri)
	if err != nil {
		return nil, err
	}
	ret := ResourceCascadeResult{
		Matched: matched,
		Msg:     msg,
	}
	return &ret, nil
}
