// Package port defines interface contracts for external adapters.
package port

import (
	"context"

	"github.com/orchard9/rdev/internal/domain"
)

// CodeAgent defines operations for executing AI coding agent commands.
// Implementations handle the specifics of different agent backends
// (Claude Code CLI, OpenCode HTTP API, etc.).
type CodeAgent interface {
	// Name returns a human-readable name for this agent implementation.
	Name() string

	// Provider returns the agent provider identifier.
	Provider() domain.AgentProvider

	// Execute runs an agent command and streams events to the handler.
	// The handler is called for each event during execution.
	// Returns the final result when execution completes.
	Execute(ctx context.Context, req *domain.AgentRequest, handler domain.AgentEventHandler) (*domain.AgentResult, error)

	// Cancel attempts to cancel a running agent session.
	// Returns nil if cancellation was successful or session not found.
	Cancel(ctx context.Context, sessionID string) error

	// Capabilities returns what this agent implementation supports.
	Capabilities() domain.AgentCapabilities

	// Available returns true if the agent is ready to accept requests.
	// This may check connectivity to external services.
	Available(ctx context.Context) bool
}

// CodeAgentRegistry manages registered code agent implementations.
// It allows looking up agents by provider and setting defaults.
type CodeAgentRegistry interface {
	// Register adds an agent implementation for a provider.
	// Overwrites any existing registration for the same provider.
	Register(agent CodeAgent)

	// Get returns the agent for a specific provider.
	// Returns nil if no agent is registered for that provider.
	Get(provider domain.AgentProvider) CodeAgent

	// Default returns the default agent implementation.
	// Returns nil if no agents are registered.
	Default() CodeAgent

	// DefaultProvider returns the current default provider.
	// Returns empty string if no agents are registered.
	DefaultProvider() domain.AgentProvider

	// SetDefault sets which provider should be used as the default.
	// Returns error if the provider is not registered.
	SetDefault(provider domain.AgentProvider) error

	// Available returns all registered providers.
	Available() []domain.AgentProvider

	// AvailableAgents returns all registered agents that are currently available.
	AvailableAgents(ctx context.Context) []CodeAgent

	// Count returns the number of registered agents.
	Count() int
}
