"""
Asset/Inventar Model
"""
from enum import Enum
from sqlalchemy import Column, Integer, String, Enum as SQLEnum, DateTime, Text, ForeignKey, Boolean
from sqlalchemy.orm import relationship
from app.models.base import Base, TimestampMixin


class AssetSource(str, Enum):
    """Quelle des Assets"""
    WAZUH = "wazuh"
    MANUAL = "manual"


class AssetStatus(str, Enum):
    """Status des Assets"""
    ACTIVE = "active"
    INACTIVE = "inactive"
    DECOMMISSIONED = "decommissioned"


from app.models.group import asset_groups

class Asset(Base, TimestampMixin):
    """
    Asset-Tabelle für Inventar-Management

    Unterstützt sowohl Wazuh-Agents als auch manuell erfasste Systeme
    """
    __tablename__ = "assets"

    id = Column(Integer, primary_key=True, index=True)

    # Identifikation
    hostname = Column(String(255), nullable=False, index=True)
    ip_address = Column(String(45), nullable=True, index=True)  # IPv6 unterstützt
    wazuh_agent_id = Column(String(10), unique=True, nullable=True, index=True)
    # Nessus host UUID — pinned after first hostname/IP match so future Nessus
    # syncs reconnect deterministically even if hostname or IP changes.
    nessus_host_uuid = Column(String(64), nullable=True, index=True)

    # System-Information
    operating_system = Column(String(255), nullable=True)
    os_version = Column(String(100), nullable=True)
    kernel_version = Column(String(100), nullable=True)
    # Plan E — Unified Risk Score inputs
    # criticality multiplier feeds into URS: low ×0.7 | normal ×1.0 |
    # high ×1.3 | critical ×1.5 (capped at 100).
    criticality = Column(String(16), nullable=False, server_default="normal")
    # JSON array of mandatory compliance frameworks, e.g. ["iso_27001","nis2"].
    # Used by per-framework URS breakdown + framework-coverage report.
    compliance_frameworks = Column(Text, nullable=True)

    # Metadata
    source = Column(
        SQLEnum(AssetSource),
        default=AssetSource.MANUAL,
        nullable=False,
        index=True
    )
    status = Column(
        SQLEnum(AssetStatus),
        default=AssetStatus.ACTIVE,
        nullable=False,
        index=True
    )

    # Scanning
    last_scan = Column(DateTime, nullable=True)
    last_seen = Column(DateTime, nullable=True)

    # Zusätzliche Informationen
    description = Column(Text, nullable=True)
    location = Column(String(255), nullable=True)
    owner = Column(String(255), nullable=True)

    # Assignment
    # Assignment
    assigned_user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True)
    # assigned_group_id -> Removed in favor of M2M
    
    # Relationships
    assigned_user = relationship("User", foreign_keys=[assigned_user_id])
    groups = relationship("Group", secondary=asset_groups, back_populates="assets")
    vulnerabilities = relationship(
        "Vulnerability",
        back_populates="asset",
        cascade="all, delete-orphan"
    )
    scans = relationship(
        "Scan",
        back_populates="asset",
        cascade="all, delete-orphan"
    )

    # Policy Linking
    policy_id = Column(Integer, ForeignKey("policies.id"), nullable=True)
    policy = relationship("Policy", back_populates="assets")

    def __repr__(self):
        return f"<Asset(hostname='{self.hostname}', ip='{self.ip_address}')>"
