package server

import (
	"context"

	"github.com/tidbcloud/AgentTeam/internal/api/extension"
	"github.com/tidbcloud/AgentTeam/internal/coredb"
	"github.com/tidbcloud/AgentTeam/internal/service/extensionflow"
)

// extensionAccessAdapter delegates to the shared extensionflow.Service
// projection so the Agent's full authorized Extension surface appears in the
// /runtime/ext route. Durable revision/state remain server-internal.
type extensionAccessAdapter struct {
	service AgentCatalogProjection
}

// AgentCatalogProjection is the extensionflow.Service surface the adapter needs:
// the Agent's authorized catalog entries (extension + app-kind + default-allow)
// and the consistent snapshot (entries + hint in one tx).
type AgentCatalogProjection interface {
	AgentCatalogEntries(ctx context.Context, workspaceID, agentID string) ([]extensionflow.AgentCatalogEntry, error)
	AgentCatalogSnapshot(ctx context.Context, workspaceID, agentID string) (extensionflow.AgentCatalogSnapshot, error)
}

func newExtensionAccessAdapter(
	_ coredb.DB,
	service AgentCatalogProjection,
) *extensionAccessAdapter {
	return &extensionAccessAdapter{service: service}
}

func (a *extensionAccessAdapter) ActiveAgentDomains(ctx context.Context, workspaceID, agentID string) ([]extension.AgentDomainAccess, error) {
	if a.service == nil {
		return nil, nil
	}
	entries, err := a.service.AgentCatalogEntries(ctx, workspaceID, agentID)
	if err != nil {
		return nil, err
	}
	result := make([]extension.AgentDomainAccess, 0, len(entries))
	for _, e := range entries {
		result = append(result, extension.AgentDomainAccess{
			Domain:            e.Domain,
			DefinitionVersion: e.DefinitionVersion,
			DefinitionDigest:  e.DefinitionDigest,
			ExtensionName:     e.ExtensionName,
			Actions:           e.Actions,
		})
	}
	return result, nil
}

// AgentCatalogSnapshot returns the Agent's catalog entries after the service
// has verified them against the durable state in one transaction.
func (a *extensionAccessAdapter) AgentCatalogSnapshot(ctx context.Context, workspaceID, agentID string) (extension.CatalogSnapshot, error) {
	snap, err := a.service.AgentCatalogSnapshot(ctx, workspaceID, agentID)
	if err != nil {
		return extension.CatalogSnapshot{}, err
	}
	domains := make([]extension.AgentDomainAccess, 0, len(snap.Entries))
	for _, e := range snap.Entries {
		domains = append(domains, extension.AgentDomainAccess{
			Domain:            e.Domain,
			DefinitionVersion: e.DefinitionVersion,
			DefinitionDigest:  e.DefinitionDigest,
			ExtensionName:     e.ExtensionName,
			Actions:           e.Actions,
		})
	}
	return extension.CatalogSnapshot{Domains: domains}, nil
}
