package dispatcher

import (
	"sync"
	"time"

	"github.com/tidbcloud/AgentTeam/desktop/internal/api/exec"
	"github.com/tidbcloud/AgentTeam/desktop/internal/types"
)

// Dispatcher service facets keep high-churn responsibilities out of the
// top-level Dispatcher method set while preserving the existing public API
// through Go method promotion on the embedded fields below.
type runtimeProcessService struct{ *Dispatcher }

type memoryService struct{ *Dispatcher }

type skillService struct{ *Dispatcher }

type knowledgeBaseService struct{ *Dispatcher }

type execAuthorizationService struct {
	*Dispatcher

	mu                  sync.Mutex
	authorizations      map[string]*execAuthorizationOwner
	pendingActivations  int
	admissionClosed     bool
	credentialFactory   func(string) (execCredential, error)
	now                 func() time.Time
	wait                func(<-chan struct{}, time.Duration) bool
	cleanupRetryWait    func(time.Duration)
	authorizationRevoke func(string) <-chan struct{}
}

type extensionRuntimeService struct {
	*Dispatcher

	catalogMu sync.RWMutex
	desired   map[extensionCatalogKey]types.ExtensionCatalogHint
	published map[extensionCatalogKey]int64
	snapshots map[extensionCatalogKey]exec.ExtensionSnapshot
}

func (d *Dispatcher) initServices() {
	if d == nil {
		return
	}
	if d.runtimeProcessService == nil {
		d.runtimeProcessService = &runtimeProcessService{Dispatcher: d}
	}
	if d.memoryService == nil {
		d.memoryService = &memoryService{Dispatcher: d}
	}
	if d.skillService == nil {
		d.skillService = &skillService{Dispatcher: d}
	}
	if d.knowledgeBaseService == nil {
		d.knowledgeBaseService = &knowledgeBaseService{Dispatcher: d}
	}
	if d.execAuthorizationService == nil {
		d.execAuthorizationService = &execAuthorizationService{Dispatcher: d}
	}
	if d.extensionRuntimeService == nil {
		d.extensionRuntimeService = &extensionRuntimeService{
			Dispatcher: d,
			desired:    make(map[extensionCatalogKey]types.ExtensionCatalogHint),
			published:  make(map[extensionCatalogKey]int64),
			snapshots:  make(map[extensionCatalogKey]exec.ExtensionSnapshot),
		}
	}
}
