from pydantic import BaseModel, Field, ConfigDict
from typing import List, Optional

class RipeModel(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
        extra="ignore"
    )

    def ripe_serialize(self):
        return self.model_dump(by_alias=True, exclude_none=True)

    @classmethod
    def ripe_deserialize(cls, data):
        return cls.model_validate(data)

class Link(RipeModel):
    xlink_type: Optional[str] = Field(
        default=None,
        validation_alias="type",
        serialization_alias="type"
    )
    xlink_href: Optional[str] = Field(
        default=None,
        validation_alias="href",
        serialization_alias="href"
    )

class InverseAttribute(RipeModel):
    value: Optional[str] = None

class InverseLookup(RipeModel):
    inverse_attribute: Optional[List[InverseAttribute]] = Field(
        default=None,
        validation_alias="inverse-attribute",
        serialization_alias="inverse-attribute"
    )

class TypeFilter(RipeModel):
    id: Optional[str] = None

class TypeFilters(RipeModel):
    type_filter: Optional[List[TypeFilter]] = Field(
        default=None,
        validation_alias="type-filter",
        serialization_alias="type-filter"
    )

class Flag(RipeModel):
    value: Optional[str] = None

class Flags(RipeModel):
    flag: Optional[List[Flag]] = None

class QueryString(RipeModel):
    value: Optional[str] = None

class QueryStrings(RipeModel):
    query_string: Optional[List[QueryString]] = Field(
        default=None,
        validation_alias="query-string",
        serialization_alias="query-string"
    )

class Source(RipeModel):
    name: Optional[str] = None
    id: Optional[str] = None

class Sources(RipeModel):
    source: Optional[List[Source]] = None

class Parameters(RipeModel):
    inverse_lookup: Optional[InverseLookup] = Field(
        default=None,
        validation_alias="inverse-lookup",
        serialization_alias="inverse-lookup"
    )
    type_filters: Optional[TypeFilters] = Field(
        default=None,
        validation_alias="type-filters",
        serialization_alias="type-filters"
    )
    flags: Optional[Flags] = None
    query_strings: Optional[QueryStrings] = Field(
        default=None,
        validation_alias="query-strings",
        serialization_alias="query-strings"
    )
    sources: Optional[Sources] = None

class Attribute(RipeModel):
    link: Optional[Link] = None
    name: Optional[str] = None
    value: Optional[str] = None
    referenced_type: Optional[str] = Field(
        default=None,
        validation_alias="referenced-type",
        serialization_alias="referenced-type"
    )
    managed: Optional[bool] = None

class Attributes(RipeModel):
    attribute: Optional[List[Attribute]] = None

class Tag(RipeModel):
    id: Optional[str] = None
    data: Optional[str] = None

class Tags(RipeModel):
    tag: Optional[List[Tag]] = None

class AbuseContact(RipeModel):
    key: Optional[str] = None
    email: Optional[str] = None
    suspect: Optional[bool] = None
    org_id: Optional[str] = Field(
        default=None,
        validation_alias="org-id",
        serialization_alias="org-id"
    )

class ResourceHolder(RipeModel):
    key: Optional[str] = None
    name: Optional[str] = None

class Object(RipeModel):
    type: Optional[str] = None
    link: Optional[Link] = None
    source: Optional[Source] = None
    primary_key: Optional[Attributes] = Field(
        default=None,
        validation_alias="primary-key",
        serialization_alias="primary-key"
    )
    attributes: Optional[Attributes] = None
    tags: Optional[Tags] = None
    abuse_contact: Optional[AbuseContact] = Field(
        default=None,
        validation_alias="abuse-contact",
        serialization_alias="abuse-contact"
    )
    resource_holder: Optional[ResourceHolder] = Field(
        default=None,
        validation_alias="resource-holder",
        serialization_alias="resource-holder"
    )

class Objects(RipeModel):
    object: Optional[List[Object]] = None

class Location(RipeModel):
    link: Optional[Link] = None
    value: Optional[str] = None

class GeolocationAttributes(RipeModel):
    location: Optional[List[Location]] = None

class GrsSource(RipeModel):
    name: Optional[str] = None
    id: Optional[str] = None
    grs_id: Optional[str] = Field(
        default=None,
        validation_alias="grs-id",
        serialization_alias="grs-id"
    )

class GrsSources(RipeModel):
    source: Optional[List[GrsSource]] = None

class Version(RipeModel):
    deleted: Optional[bool] = None
    revision: Optional[str] = None
    date: Optional[str] = None
    operation: Optional[str] = None

class Versions(RipeModel):
    type: Optional[str] = None
    key: Optional[str] = None
    version: Optional[List[Version]] = None

class Arg(RipeModel):
    value: Optional[str] = None

class ErrorMessage(RipeModel):
    severity: Optional[str] = None
    text: Optional[str] = None
    args: Optional[List[Arg]] = None

class ErrorMessages(RipeModel):
    errormessage: Optional[List[ErrorMessage]] = Field(
        default=None,
        validation_alias="errormessage",
        serialization_alias="errormessage"
    )

class RipeSoftwareVersion(RipeModel):
    version: Optional[str] = None
    timestamp: Optional[str] = None
    commit_id: Optional[str] = Field(
        default=None,
        validation_alias="commit-id",
        serialization_alias="commit-id"
    )

class WhoisResources(RipeModel):
    parameters: Optional[Parameters] = None
    objects: Optional[Objects] = None
    geolocation_attributes: Optional[GeolocationAttributes] = Field(
        default=None,
        validation_alias="geolocation-attributes",
        serialization_alias="geolocation-attributes"
    )
    grs_sources: Optional[GrsSources] = Field(
        default=None,
        validation_alias="grs-sources",
        serialization_alias="grs-sources"
    )
    versions: Optional[Versions] = None
    errormessages: Optional[ErrorMessages] = Field(
        default=None,
        validation_alias="errormessages",
        serialization_alias="errormessages"
    )
    terms_and_conditions: Optional[Link] = Field(
        default=None,
        validation_alias="terms-and-conditions",
        serialization_alias="terms-and-conditions"
    )
    version: Optional[RipeSoftwareVersion] = None
