# Automatically generated by generate_types.py. Do not edit manually.
import enum
import re
from typing import Optional

from pydantic import field_validator, Field

from .base import CommonEntityType, load_entity_supported_types

__all__ = ["ObservableType", "ObservableTypes"]


class ObservableType(CommonEntityType):
    """ObservableType represents metadata for observables in Colander.

    Check :ref:`the list of supported types <observable_types>`.

    Example:
        >>> observable_type = ObservableType(
        ...     short_name='IPV4',
        ...     name='IPv4',
        ...     description='An IPv4 address type'
        ... )
        >>> print(observable_type.name)
        IPv4
    """

    regex: str = Field(default="", exclude=True)
    _compiled_regex: Optional[re.Pattern] = None

    def model_post_init(self, __context):
        if self.regex:
            self._compiled_regex = re.compile(self.regex, re.IGNORECASE)

    @field_validator("short_name", mode="before")
    @classmethod
    def is_supported_type(cls, short_name: str):
        if short_name not in {t["short_name"] for t in load_entity_supported_types("observable")}:
            raise ValueError(f"{short_name} is not supported")
        return short_name

    def match_regex(self, value: str) -> bool:
        """Check if a value matches the compiled regex pattern for this observable type.

        This method validates whether a given string value conforms to the regex pattern
        defined for this observable type. If no regex pattern is configured, it returns False.

        Args:
            value (str): The string value to test against the regex pattern.

        Returns:
            bool: True if the value matches the regex pattern, False otherwise.
            Returns False if no regex pattern is configured for this type.

        Example:
            >>> ipv4_type = ObservableTypes.IPV4.value
            >>> ipv4_type.match_regex("192.168.1.1")
            True
            >>> ipv4_type.match_regex("invalid-ip")
            False
        """
        if self._compiled_regex:
            return bool(self._compiled_regex.match(value))
        else:
            return False


class ObservableTypes(enum.Enum):
    """ObservableTypes provides access to all supported observable types.

    This class loads observable type definitions from the observable types JSON file and exposes them as an enum.
    It also provides a method to look up an observable type by its short name.

    Example:
        >>> observable_type = ObservableTypes.IPV4.value
        >>> print(observable_type.name)
        IPv4
        >>> default_type = ObservableTypes.by_short_name("nonexistent")
        >>> print(default_type.name)
        Generic
    """

    ASN = ObservableType(
        **{
            "short_name": "ASN",
            "name": "Autonomous system number",
            "description": "A unique number assigned to a group of IP networks operated by one or more network operators.",
            "default_attributes": {"organization": ""},
            "icon": "",
            "nf_icon": "nf-mdi-web",
            "regex": "^AS[0-9]+$",
            "value_example": "AS15169",
        }
    )
    """Autonomous system number - A unique number assigned to a group of IP networks operated by one or more network operators."""

    CIDR = ObservableType(
        **{
            "short_name": "CIDR",
            "name": "CIDR",
            "description": "A Classless Inter-Domain Routing block, representing a range of IP addresses.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-mdi-ethernet",
            "regex": "^((?:(?:25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d))\\/(3[0-2]|[12]?\\d)$",
            "value_example": "192.0.2.0/24",
        }
    )
    """CIDR - A Classless Inter-Domain Routing block, representing a range of IP addresses."""

    COMMUNITY_ID = ObservableType(
        **{
            "short_name": "COMMUNITY_ID",
            "name": "Community id",
            "description": "A hash value used to uniquely identify network flows across tools.",
            "default_attributes": {"src_ip": "", "src_port": "", "dst_ip": "", "dst_port": ""},
            "icon": "",
            "nf_icon": "nf-fa-hashtag",
            "regex": "",
            "value_example": "1:hJ4jHqT3mUo4xXH7j0v3JY2F1hw=",
        }
    )
    """Community id - A hash value used to uniquely identify network flows across tools."""

    CVE = ObservableType(
        **{
            "short_name": "CVE",
            "name": "CVE",
            "description": "A Common Vulnerabilities and Exposures identifier for publicly known security flaws.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-cod-debug_console",
            "regex": "^CVE-\\d{4}-\\d{4,}$",
            "value_example": "CVE-2021-44228",
        }
    )
    """CVE - A Common Vulnerabilities and Exposures identifier for publicly known security flaws."""

    DEXOFUZZY = ObservableType(
        **{
            "short_name": "DEXOFUZZY",
            "name": "Dexofuzzy hash",
            "description": "A fuzzy hash value used to compare Android DEX files for similarity.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-fa-hashtag",
            "regex": "",
            "value_example": "3:abcde:12345",
        }
    )
    """Dexofuzzy hash - A fuzzy hash value used to compare Android DEX files for similarity."""

    DNS_RECORD = ObservableType(
        **{
            "short_name": "DNS_RECORD",
            "name": "DNS record",
            "description": "A record containing information about a domain name in the DNS system.",
            "default_attributes": {
                "resolver": "",
                "domain": "",
                "a": "",
                "aaaa": "",
                "cname": "",
                "mx": "",
                "ns": "",
                "ptr": "",
                "soa": "",
                "spf": "",
                "srv": "",
                "txt": "",
            },
            "icon": "",
            "nf_icon": "nf-mdi-web",
            "regex": "",
            "value_example": "A example.com 192.0.2.1",
        }
    )
    """DNS record - A record containing information about a domain name in the DNS system."""

    DOMAIN = ObservableType(
        **{
            "short_name": "DOMAIN",
            "name": "Domain name",
            "description": "A human-readable address used to identify resources on the internet.",
            "default_attributes": {"root_domain": "", "registration_date": ""},
            "icon": "",
            "nf_icon": "nf-mdi-web",
            "regex": "^(?=.{1,253}$)(?!-)[a-zA-Z0-9-]{1,63}(?<!-)(\\.(?!-)[a-zA-Z0-9-]{1,63}(?<!-))*\\.[a-zA-Z]{2,}$",
            "value_example": "example.com",
        }
    )
    """Domain name - A human-readable address used to identify resources on the internet."""

    DOMAIN_REGISTRANT = ObservableType(
        **{
            "short_name": "DOMAIN_REGISTRANT",
            "name": "Domain registrant",
            "description": "The individual or organization that owns or controls a domain name.",
            "default_attributes": {
                "name": "",
                "organization": "",
                "street": "",
                "city": "",
                "state": "",
                "postal_code": "",
                "country": "",
                "phone": "",
                "fax": "",
                "email": "",
            },
            "icon": "",
            "nf_icon": "nf-mdi-web",
            "regex": "",
            "value_example": "Example Organization",
        }
    )
    """Domain registrant - The individual or organization that owns or controls a domain name."""

    DOMAIN_REGISTRAR = ObservableType(
        **{
            "short_name": "DOMAIN_REGISTRAR",
            "name": "Domain registrar",
            "description": "The organization or entity responsible for registering domain names.",
            "default_attributes": {
                "name": "",
                "organization": "",
                "street": "",
                "city": "",
                "state": "",
                "postal_code": "",
                "country": "",
                "phone": "",
                "fax": "",
                "email": "",
            },
            "icon": "",
            "nf_icon": "nf-mdi-web",
            "regex": "",
            "value_example": "GitHub Inc.",
        }
    )
    """Domain registrar - The organization or entity responsible for registering domain names."""

    EMAIL = ObservableType(
        **{
            "short_name": "EMAIL",
            "name": "Email address",
            "description": "An address used to send and receive electronic mail.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-mdi-email_outline",
            "regex": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
            "value_example": "user@example.com",
        }
    )
    """Email address - An address used to send and receive electronic mail."""

    GENERIC = ObservableType(
        **{
            "short_name": "GENERIC",
            "name": "Generic",
            "description": "A general or unspecified observable type that does not fit other categories.",
            "icon": "",
            "nf_icon": "nf nf-fa-bug",
            "regex": "",
            "value_example": "",
        }
    )
    """Generic - A general or unspecified observable type that does not fit other categories."""

    HOSTNAME = ObservableType(
        **{
            "short_name": "HOSTNAME",
            "name": "Hostname",
            "description": "A label assigned to a device on a network, used to identify it in various forms.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-mdi-web",
            "regex": "",
            "value_example": "host1.internal",
        }
    )
    """Hostname - A label assigned to a device on a network, used to identify it in various forms."""

    IMPHASH = ObservableType(
        **{
            "short_name": "IMPHASH",
            "name": "Import hash",
            "description": "A hash of the import table of a PE file, used to identify similar binaries.",
            "default_attributes": {"pehash": "pehash", "impfuzzy": "impfuzzy"},
            "icon": "",
            "nf_icon": "nf-fa-hashtag",
            "regex": "",
            "value_example": "1a2b3c4d5e6f7890",
        }
    )
    """Import hash - A hash of the import table of a PE file, used to identify similar binaries."""

    IPV4 = ObservableType(
        **{
            "short_name": "IPV4",
            "name": "IPv4",
            "description": "An IPv4 address, a 32-bit numeric address used for identifying devices on a network.",
            "default_attributes": {"address_block": "", "subnet": "", "routable": "", "ASN": ""},
            "icon": "",
            "nf_icon": "nf-mdi-ethernet",
            "regex": "^(?:(?:25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)$",
            "value_example": "192.0.2.1",
        }
    )
    """IPv4 - An IPv4 address, a 32-bit numeric address used for identifying devices on a network."""

    IPV6 = ObservableType(
        **{
            "short_name": "IPV6",
            "name": "IPv6",
            "description": "An IPv6 address, a 128-bit alphanumeric address for identifying devices on a network.",
            "default_attributes": {"address_block": "", "subnet": "", "routable": "", "ASN": ""},
            "icon": "",
            "nf_icon": "nf-mdi-ethernet",
            "regex": "^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|::ffff:(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d))$",
            "value_example": "2001:db8::1",
        }
    )
    """IPv6 - An IPv6 address, a 128-bit alphanumeric address for identifying devices on a network."""

    LOCATION = ObservableType(
        **{
            "short_name": "LOCATION",
            "name": "Location",
            "description": "A physical or geographical place, specified by coordinates or address.",
            "default_attributes": {
                "latitude": "",
                "longitude": "",
                "altitude": "",
                "country": "",
                "state": "",
                "city": "",
                "address": "",
            },
            "icon": "",
            "nf_icon": "nf-fa-globe",
            "regex": "",
            "value_example": "37.4219983,-122.084",
        }
    )
    """Location - A physical or geographical place, specified by coordinates or address."""

    MAC = ObservableType(
        **{
            "short_name": "MAC",
            "name": "MAC address",
            "description": "A unique hardware identifier assigned to a network interface card (NIC).",
            "default_attributes": {"manufacturer": ""},
            "icon": "",
            "nf_icon": "nf-mdi-ethernet",
            "regex": "^([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}$",
            "value_example": "00:1A:2B:3C:4D:5E",
        }
    )
    """MAC address - A unique hardware identifier assigned to a network interface card (NIC)."""

    MD5 = ObservableType(
        **{
            "short_name": "MD5",
            "name": "MD5",
            "description": "A 128-bit hash value, commonly used to verify file integrity.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-fa-hashtag",
            "regex": "^[a-fA-F0-9]{32}$",
            "value_example": "d41d8cd98f00b204e9800998ecf8427e",
        }
    )
    """MD5 - A 128-bit hash value, commonly used to verify file integrity."""

    MUTEX = ObservableType(
        **{
            "short_name": "MUTEX",
            "name": "Mutex",
            "description": "A mutual exclusion object used for process synchronization.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-mdi-pencil_lock",
            "regex": "",
            "value_example": "Global\\MyAppMutex",
        }
    )
    """Mutex - A mutual exclusion object used for process synchronization."""

    NAMESPACE = ObservableType(
        **{
            "short_name": "NAMESPACE",
            "name": "Namespace",
            "description": "A container that holds a set of identifiers, such as classes or functions, to avoid naming conflicts.",
            "default_attributes": {"fully_qualified_name": ""},
            "icon": "",
            "nf_icon": "nf-md-code_tags",
            "regex": "",
            "value_example": "com.example.app.module",
        }
    )
    """Namespace - A container that holds a set of identifiers, such as classes or functions, to avoid naming conflicts."""

    OS_QUERY = ObservableType(
        **{
            "short_name": "OS_QUERY",
            "name": "Os query",
            "description": "A query or result from an operating system instrumentation framework.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-cod-inspect",
            "regex": "",
            "value_example": "select * from processes where name='ssh';",
        }
    )
    """Os query - A query or result from an operating system instrumentation framework."""

    PATH = ObservableType(
        **{
            "short_name": "PATH",
            "name": "File path",
            "description": "A string specifying the location of a file or directory in a filesystem.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-mdi-file_tree",
            "regex": "^([a-zA-Z]:[\\\\]|[\\\\]{2}[^\\\\]+[\\\\]|[\\/])?([\\w\\-. ]+[\\/\\\\])*[\\w\\-. ]+$",
            "value_example": "/var/log/syslog",
        }
    )
    """File path - A string specifying the location of a file or directory in a filesystem."""

    PEHASH = ObservableType(
        **{
            "short_name": "PEHASH",
            "name": "PE hash",
            "description": "A hash value calculated from the structure of a Portable Executable (PE) file.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-fa-hashtag",
            "regex": "",
            "value_example": "3f2a9b7c",
        }
    )
    """PE hash - A hash value calculated from the structure of a Portable Executable (PE) file."""

    PHONE = ObservableType(
        **{
            "short_name": "PHONE",
            "name": "Phone number",
            "description": "A numeric identifier used to reach a telephone endpoint.",
            "default_attributes": {"prefix": "", "country_code": "", "country_name": ""},
            "icon": "",
            "nf_icon": "nf-fa-phone",
            "regex": "^(\\+\\d{1,3}[-.\\s]?)?(\\(?\\d{1,4}\\)?[-.\\s]?)*\\d{1,4}$",
            "value_example": "+1 202-555-0143",
        }
    )
    """Phone number - A numeric identifier used to reach a telephone endpoint."""

    PROCESS = ObservableType(
        **{
            "short_name": "PROCESS",
            "name": "Process name",
            "description": "The name of a running process on a computer system.",
            "default_attributes": {"executable": "", "path": ""},
            "icon": "",
            "nf_icon": "nf-cod-debug_console",
            "regex": "",
            "value_example": "chrome.exe",
        }
    )
    """Process name - The name of a running process on a computer system."""

    SERVICE = ObservableType(
        **{
            "short_name": "SERVICE",
            "name": "Running service",
            "description": "A network or system service that is currently active or listening.",
            "default_attributes": {"ip_address": "", "technology": "", "port": ""},
            "icon": "",
            "nf_icon": "nf-mdi-web",
            "regex": "",
            "value_example": "80/tcp open http",
        }
    )
    """Running service - A network or system service that is currently active or listening."""

    SHA1 = ObservableType(
        **{
            "short_name": "SHA1",
            "name": "SHA1",
            "description": "A 160-bit hash value, used for data integrity and file identification.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-fa-hashtag",
            "regex": "^[a-fA-F0-9]{40}$",
            "value_example": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
        }
    )
    """SHA1 - A 160-bit hash value, used for data integrity and file identification."""

    SHA256 = ObservableType(
        **{
            "short_name": "SHA256",
            "name": "SHA256",
            "description": "A 256-bit hash value, widely used for file and data integrity verification.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-fa-hashtag",
            "regex": "^[a-fA-F0-9]{64}$",
            "value_example": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
        }
    )
    """SHA256 - A 256-bit hash value, widely used for file and data integrity verification."""

    SOCIAL_ACCOUNT = ObservableType(
        **{
            "short_name": "SOCIAL_ACCOUNT",
            "name": "Social account identifier",
            "description": "A unique identifier for a user account on a social media platform.",
            "default_attributes": {"platform": ""},
            "icon": "",
            "nf_icon": "nf-mdi-account_card_details",
            "regex": "",
            "value_example": "@example_user",
        }
    )
    """Social account identifier - A unique identifier for a user account on a social media platform."""

    SSL_CERT_F = ObservableType(
        **{
            "short_name": "SSL_CERT_F",
            "name": "SSL certificate fingerprint",
            "description": "A hash value uniquely identifying an SSL/TLS certificate.",
            "default_attributes": {
                "subject": "",
                "md5": "",
                "sha1": "",
                "sha256": "",
                "issuer": "",
                "organization": "",
                "not_before": "",
                "not_after": "",
            },
            "icon": "",
            "nf_icon": "nf-mdi-certificate",
            "regex": "",
            "value_example": "SHA256 Fingerprint=AB:CD:EF:...",
        }
    )
    """SSL certificate fingerprint - A hash value uniquely identifying an SSL/TLS certificate."""

    URI = ObservableType(
        **{
            "short_name": "URI",
            "name": "URI",
            "description": "A Uniform Resource Identifier, a string used to identify a resource.",
            "default_attributes": {},
            "icon": "",
            "nf_icon": "nf-mdi-web",
            "regex": "^[a-zA-Z][a-zA-Z0-9+.-]*:[^\\s]*$",
            "value_example": "urn:isbn:0451450523",
        }
    )
    """URI - A Uniform Resource Identifier, a string used to identify a resource."""

    URL = ObservableType(
        **{
            "short_name": "URL",
            "name": "URL",
            "description": "A Uniform Resource Locator, specifying the address of a resource on the internet.",
            "default_attributes": {"query_string": "", "resource_path": "", "scheme": "", "domain": ""},
            "icon": "",
            "nf_icon": "nf-mdi-web",
            "regex": "^(https?|ftp):\\/\\/[a-zA-Z0-9.-]+(:[0-9]+)?(\\/[^\\s]*)?$",
            "value_example": "https://example.com/path?query=1",
        }
    )
    """URL - A Uniform Resource Locator, specifying the address of a resource on the internet."""

    default = GENERIC  # type: ignore[attr-defined]

    @classmethod
    def by_short_name(cls, short_name: str) -> ObservableType:
        sn = short_name.replace(" ", "_").upper()
        if sn in cls._member_names_:
            return cls[sn].value
        return cls.default.value

    @classmethod
    def suggest(cls, observable_value) -> ObservableType:
        """Suggest an appropriate observable type based on pattern matching.

        This method attempts to find a suitable observable type by testing the given
        observable name against the regex patterns of all defined observable types.
        It returns the first matching type found, or the default generic type if no
        pattern matches.

        Args:
            observable_value (str): The observable value to analyze and match against
                known patterns (e.g., IP addresses, domains, hashes).

        Returns:
            ObservableType: The first observable type whose regex pattern matches
            the input, or the default GENERIC type if no match is found.

        Example:
            >>> ObservableTypes.suggest("192.168.1.1")
            IPV4
            >>> ObservableTypes.suggest("example.com")
            DOMAIN
        """
        for _observable_type in cls:
            if _observable_type.value.match_regex(observable_value):
                return _observable_type.value
        return cls.default.value
