package hostruntime

import (
	"context"
	"time"
)

// PermissionProvider loads the bounded permission facts owned by request
// middleware. Object and field projections remain in the authorization engine;
// keeping all-object loaders out of this contract prevents a request cache miss
// from scheduling tenant-wide permission work.
type PermissionProvider interface {
	GetEffectiveSystemPermissions(ctx context.Context, userID, profileID string) (map[string]bool, error)
	GetEffectiveCustomPermissions(ctx context.Context, userID, profileID string) (map[string]bool, error)
}

// PermissionDiagnosticsSnapshot is a stable, loggable copy of request-scoped
// permission diagnostics.
type PermissionDiagnosticsSnapshot struct {
	SystemCalls             int
	SystemDuration          time.Duration
	CustomCalls             int
	CustomDuration          time.Duration
	RecordTypeCalls         int
	RecordTypeRows          int
	RecordTypeDur           time.Duration
	ObjectDBFallbacks       int
	ObjectDBDuration        time.Duration
	ObjectCacheHits         int
	FieldDBFallbacks        int
	FieldDBDuration         time.Duration
	FieldCacheHits          int
	ObjectBulkCalls         int
	ObjectBulkRows          int
	ObjectBulkDuration      time.Duration
	FieldBulkCalls          int
	FieldBulkRows           int
	FieldBulkDuration       time.Duration
	FieldBulkRejected       int
	EffectiveAccessCalls    int
	EffectiveAccessFields   int
	EffectiveAccessDuration time.Duration
}

func (s PermissionDiagnosticsSnapshot) HasWork() bool {
	return s.SystemCalls+s.CustomCalls+s.RecordTypeCalls+
		s.ObjectDBFallbacks+s.FieldDBFallbacks+
		s.ObjectBulkCalls+s.FieldBulkCalls+s.FieldBulkRejected+
		s.EffectiveAccessCalls > 0
}

// PermissionRequestContext installs and reads request-scoped permission/cache
// context without exposing the host runtime to kernel package context keys.
type PermissionRequestContext interface {
	Install(ctx context.Context) context.Context
	Snapshot(ctx context.Context) PermissionDiagnosticsSnapshot
}

type noopPermissionRequestContext struct{}

func (noopPermissionRequestContext) Install(ctx context.Context) context.Context {
	return ctx
}

func (noopPermissionRequestContext) Snapshot(context.Context) PermissionDiagnosticsSnapshot {
	return PermissionDiagnosticsSnapshot{}
}

// NormalizePermissionRequestContext returns a no-op installer when no backend
// adapter has been supplied.
func NormalizePermissionRequestContext(installer PermissionRequestContext) PermissionRequestContext {
	if installer == nil {
		return noopPermissionRequestContext{}
	}
	return installer
}
