"""DefensiveTechnique and DefensiveTechniqueMapping models.

Stores MITRE D3FEND defensive techniques and their mappings to
ATT&CK techniques, enabling recommended countermeasure lookups.
"""

import uuid
from sqlalchemy import (
    Column, String, Text, DateTime,
    ForeignKey, Index, UniqueConstraint, func,
)
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship

from app.database import Base


class DefensiveTechnique(Base):
    """
    MITRE D3FEND defensive technique.

    Represents a countermeasure from the D3FEND framework that can be
    mapped to one or more ATT&CK techniques via DefensiveTechniqueMapping.
    """
    __tablename__ = "defensive_techniques"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    d3fend_id = Column(String, unique=True, nullable=False)          # e.g. "D3-AL"
    name = Column(String, nullable=False)
    description = Column(Text, nullable=True)
    tactic = Column(String, nullable=True)                            # Detect, Isolate, Deceive, Evict, etc.
    d3fend_url = Column(String, nullable=True)
    created_at = Column(DateTime(timezone=True), server_default=func.now())

    # Relationships
    attack_mappings = relationship(
        "DefensiveTechniqueMapping",
        back_populates="defensive_technique",
        cascade="all, delete-orphan",
    )

    __table_args__ = (
        Index('ix_defensive_techniques_tactic', 'tactic'),
    )


class DefensiveTechniqueMapping(Base):
    """
    Association between a MITRE ATT&CK technique and a D3FEND
    defensive technique.
    """
    __tablename__ = "defensive_technique_mappings"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    attack_technique_id = Column(
        UUID(as_uuid=True),
        ForeignKey("techniques.id", ondelete="CASCADE"),
        nullable=False,
    )
    defensive_technique_id = Column(
        UUID(as_uuid=True),
        ForeignKey("defensive_techniques.id", ondelete="CASCADE"),
        nullable=False,
    )

    # Relationships
    attack_technique = relationship("Technique")
    defensive_technique = relationship("DefensiveTechnique", back_populates="attack_mappings")

    __table_args__ = (
        Index('ix_dtm_attack_technique', 'attack_technique_id'),
        Index('ix_dtm_defensive_technique', 'defensive_technique_id'),
        UniqueConstraint(
            'attack_technique_id', 'defensive_technique_id',
            name='uq_attack_defensive_technique',
        ),
    )
