# app/models/syndarix/agent_type.py
"""
AgentType model for Syndarix AI consulting platform.

An AgentType is a template that defines the capabilities, personality,
and model configuration for agent instances.
"""

from sqlalchemy import Boolean, Column, Index, String, Text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import relationship

from app.models.base import Base, TimestampMixin, UUIDMixin


class AgentType(Base, UUIDMixin, TimestampMixin):
    """
    AgentType model representing a template for agent instances.

    Each agent type defines:
    - Expertise areas and personality prompt
    - Model configuration (primary, fallback, parameters)
    - MCP server access and tool permissions

    Examples: ProductOwner, Architect, BackendEngineer, QAEngineer
    """

    __tablename__ = "agent_types"

    name = Column(String(255), nullable=False, index=True)
    slug = Column(String(255), unique=True, nullable=False, index=True)
    description = Column(Text, nullable=True)

    # Areas of expertise for this agent type (e.g., ["python", "fastapi", "databases"])
    expertise = Column(JSONB, default=list, nullable=False)

    # System prompt defining the agent's personality and behavior
    personality_prompt = Column(Text, nullable=False)

    # Primary LLM model to use (e.g., "claude-opus-4-5-20251101")
    primary_model = Column(String(100), nullable=False)

    # Fallback models in order of preference
    fallback_models = Column(JSONB, default=list, nullable=False)

    # Model parameters (temperature, max_tokens, etc.)
    model_params = Column(JSONB, default=dict, nullable=False)

    # List of MCP servers this agent can connect to
    mcp_servers = Column(JSONB, default=list, nullable=False)

    # Tool permissions configuration
    # Structure: {"allowed": ["*"], "denied": [], "require_approval": ["gitea:create_pr"]}
    tool_permissions = Column(JSONB, default=dict, nullable=False)

    # Whether this agent type is available for new instances
    is_active = Column(Boolean, default=True, nullable=False, index=True)

    # Relationships
    instances = relationship(
        "AgentInstance",
        back_populates="agent_type",
        cascade="all, delete-orphan",
    )

    __table_args__ = (
        Index("ix_agent_types_slug_active", "slug", "is_active"),
        Index("ix_agent_types_name_active", "name", "is_active"),
    )

    def __repr__(self) -> str:
        return f"<AgentType {self.name} ({self.slug}) active={self.is_active}>"
