from datetime import datetime
from enum import Enum
from typing import Optional

from pydantic import BaseModel

from py_ocsf_models.events.findings.finding import Finding
from py_ocsf_models.objects.evidence_artifacts import EvidenceArtifacts
from py_ocsf_models.objects.remediation import Remediation
from py_ocsf_models.objects.resource_details import ResourceDetails
from py_ocsf_models.objects.vulnerability_details import VulnerabilityDetails
from py_ocsf_models.profiles.cloud import CloudProfile
from py_ocsf_models.profiles.container import ContainerProfile


class CategoryUID(Enum):
    """
    The category unique identifier of the event.

    2 Findings: Findings events report findings, detections, and possible resolutions of malware, anomalies, or other actions performed by security products.
    """

    Findings = 2


class ClassUID(Enum):
    """
    The unique identifier of a class. A Class describes the attributes available in an event.

    2004 DetectionFinding: A Detection Finding describes detections or alerts generated by security products using correlation engines, detection engines or other methodologies. Note: if the product is a security control, the security_control profile should be applied and its attacks information should be duplicated into the finding_info object.
    """

    DetectionFinding = 2004


class DetectionFinding(Finding, BaseModel):
    """
    A Detection Finding describes detections or alerts generated by security products using correlation engines, detection engines or other methodologies. Note: if the product is a security control, the security_control profile should be applied and its attacks information should be duplicated into the finding_info object.

    Attributes:
    - Activity ID (activity_id): The normalized identifier of the finding activity.
    - Affected Resources (resources) [Recommended]: Describes details about resources that were the target of the activity that triggered the finding.
    - Category (category_name): The event category name, as defined by category_uid value: Findings.
    - Class (class_name) [Optional]: The event class name, as defined by class_uid value: Detection Finding.
    - Class ID (class_uid): The unique identifier of a class. A Class describes the attributes available in an event.
    - Cloud (cloud) [Optional]: Describes details about the Cloud environment where the event was originally created or logged.
    - Container (container) [Optional]: Describes the container details.
    - Count (count) [Optional]: Number of times similar events occurred within a specified timeframe.
    - Duration (duration) [Optional]: Time span of the event, from start to end, in milliseconds.
    - Event Time (time) [Required]: The standardized time when the event occurred or the finding was created.
    - Evidence Artifacts (evidences) [Optional]: Artifacts related to the security detection activities.
    - Impact, Impact Score, Impact ID (impact, impact_score, impact_id) [Optional]: Describes the effect and severity of the finding.
    - Remediation Guidance (remediation) [Optional]: Suggested steps to address the finding.
    - Risk Level, Risk Score, Risk Level ID (risk_level, risk_score, risk_level_id) [Optional]: The risk associated with the finding.
    - Timezone Offset (timezone_offset) [Optional]: Difference in minutes from UTC.
    - Type ID, Type Name (type_id, type_name) [Required/Optional]: Identifiers for the event's type and description.
    - Vulnerabilities (vulnerabilities) [Optional]: Vulnerabilities identified in the finding.

    """

    # TODO: pending to add profiles
    resources: Optional[list[ResourceDetails]]
    category_name: str = "Findings"
    category_uid: CategoryUID = CategoryUID["Findings"]
    class_name: Optional[str] = "Detection Finding"
    class_uid: ClassUID = ClassUID["DetectionFinding"]
    cloud: Optional[CloudProfile]
    container: Optional[ContainerProfile]
    count: Optional[int]
    duration: Optional[int]
    event_time: datetime
    evidences: Optional[list[EvidenceArtifacts]]
    impact: Optional[str]
    impact_score: Optional[int]
    impact_id: Optional[int]
    remediation: Optional[Remediation]
    risk_level: Optional[str]
    risk_level_id: Optional[int]
    risk_score: Optional[int]
    timezone_offset: Optional[int]
    type_id: int
    type_name: Optional[str]
    vulnerabilities: Optional[list[VulnerabilityDetails]]
