# generated by datamodel-codegen:
#   filename:  metadata-container-json-schema.json
#   timestamp: 2025-12-03T08:38:27+00:00

from __future__ import annotations

from datetime import date
from enum import Enum
from typing import Any, Literal, Optional, Union
from uuid import UUID

from datadoc_model.datadoc_base_model import DatadocBaseModel
from pydantic import AnyUrl, AwareDatetime, Field, RootModel


class Assessment(str, Enum):
    SENSITIVE = "SENSITIVE"
    PROTECTED = "PROTECTED"
    OPEN = "OPEN"


class DataSetStatus(str, Enum):
    DRAFT = "DRAFT"
    INTERNAL = "INTERNAL"
    EXTERNAL = "EXTERNAL"
    DEPRECATED = "DEPRECATED"


class DataSetState(str, Enum):
    SOURCE_DATA = "SOURCE_DATA"
    INPUT_DATA = "INPUT_DATA"
    PROCESSED_DATA = "PROCESSED_DATA"
    STATISTICS = "STATISTICS"
    OUTPUT_DATA = "OUTPUT_DATA"


class UseRestrictionType(Enum):
    DELETION_ANONYMIZATION = "DELETION_ANONYMIZATION"
    PROCESS_LIMITATIONS = "PROCESS_LIMITATIONS"
    SECONDARY_USE_RESTRICTIONS = "SECONDARY_USE_RESTRICTIONS"


class UseRestrictionItem(DatadocBaseModel):
    use_restriction_type: Optional[UseRestrictionType] = Field(
        None, description="Use restriction type", title="Use restriction type"
    )
    use_restriction_date: Optional[date] = Field(
        None,
        description="Use restriction date, eg. the date (deadline) for when data must be deleted/anonymised.",
        title="Use restriction date",
    )


class CustomTypeForDatasetMetadatum(DatadocBaseModel):
    key: Optional[str] = Field(None, description="Custom type KEY", title="Key")
    value: Optional[Union[str, list[Any], dict[str, Any]]] = Field(
        None,
        description="Custom type VALUE (of type string, array or object).",
        title="Value",
    )


class DataType(str, Enum):
    STRING = "STRING"
    INTEGER = "INTEGER"
    DATETIME = "DATETIME"
    BOOLEAN = "BOOLEAN"
    FLOAT = "FLOAT"
    ARRAY = "ARRAY"


class VariableRole(str, Enum):
    IDENTIFIER = "IDENTIFIER"
    MEASURE = "MEASURE"
    START_TIME = "START_TIME"
    STOP_TIME = "STOP_TIME"
    ATTRIBUTE = "ATTRIBUTE"


class Pseudonymization(DatadocBaseModel):
    pseudonymization_time: Optional[AwareDatetime] = Field(
        None,
        description="Time at which the variable was pseudonymized. In ISO 8601 format.",
        title="Variable pseudo time",
    )
    stable_identifier_type: Optional[str] = Field(
        None,
        description="Type of stable identifier the variable was mapped to prior to pseudonymization.",
        title="Stable identifier type",
    )
    stable_identifier_version: Optional[date] = Field(
        None,
        description="Version of stable identifier the variable was mapped to prior to pseudonymization.",
        title="Stable identifier version",
    )
    encryption_algorithm: Optional[str] = Field(
        None,
        description="The encryption algorithm used to pseudonymize the variable.",
        title="Encryption algorithm",
    )
    encryption_key_reference: Optional[str] = Field(
        None,
        description="Name of or reference to the encryption key used to pseudonymize the variable.",
        title="Encryption key reference",
    )
    encryption_algorithm_parameters: Optional[list[dict[str, Any]]] = Field(
        None,
        description="Parameters supplied to the encryption algorithm.",
        title="Encryption algorithm parameters",
    )


class SentinelValues(DatadocBaseModel):
    sentinel_value_uri: Optional[AnyUrl] = Field(
        None,
        description="A link (URI) to a standardized list of sentinel values included in the variable, eg. a link to a codelist in Klass (https://www.ssb.no/en/klass/)",
        title="Sentinel value URI",
    )
    sentinel_value_elements: Optional[list[str]] = Field(
        None,
        description="A selection (subset) of sentinel values in the 'sentinel_value_uri' \u200b\u200bapplicable to the data set.",
        title="Sentinel value elements",
    )


class CustomTypeForVariableMetadatum(DatadocBaseModel):
    key: Optional[str] = Field(None, description="Custom type KEY", title="Key")
    value: Optional[Union[str, list[Any], dict[str, Any]]] = Field(
        None,
        description="Custom type VALUE (of type string, array or object).",
        title="Value",
    )


class LanguageStringTypeItem(DatadocBaseModel):
    languageCode: Optional[str] = Field(
        None, description="Language code (ISO 639-1)", title="Language code"
    )
    languageText: Optional[str] = Field(
        None, description="Language text", title="Language text"
    )


class LanguageStringType(RootModel[Optional[list[LanguageStringTypeItem]]]):
    root: Optional[list[LanguageStringTypeItem]] = None


class TemporalityTypeType(str, Enum):
    FIXED = "FIXED"
    STATUS = "STATUS"
    ACCUMULATED = "ACCUMULATED"
    EVENT = "EVENT"


class Dataset(DatadocBaseModel):
    short_name: Optional[str] = Field(
        None,
        description="Name of (physical) data file, data table or dataset",
        title="Short name",
    )
    assessment: Optional[Assessment] = Field(
        None,
        description="Value assessment (sensitivity classification) for the data set",
        title="Assessment",
    )
    dataset_status: Optional[DataSetStatus] = Field(
        None, description="Life cycle for data set", title="Data set status"
    )
    dataset_state: Optional[DataSetState] = Field(
        None, description="Steady state of data", title="Data set state"
    )
    name: Optional[LanguageStringType] = Field(
        None, description="Name of data set", title="Name"
    )
    description: Optional[LanguageStringType] = Field(
        None, description="Free text description of the data set", title="Description"
    )
    population_description: Optional[LanguageStringType] = Field(
        None,
        description="Description of the population covered in the data set. Includes unit type, spatial coverage and period of time.",
        title="Description of population",
    )
    version: Optional[str] = Field(
        None, description="Version of data set", title="Version"
    )
    version_description: Optional[LanguageStringType] = Field(
        None,
        description="Dataset version information in the form of descriptive text",
        title="Version description",
    )
    subject_field: Optional[str] = Field(
        None,
        description="Primary area of statistics in which the data set is included",
        title="Subject field",
    )
    keyword: Optional[list[str]] = Field(
        None,
        description="A list of searchable keywords that can contribute to the development of effective filtering and search services.",
        title="Keyword(s)",
    )
    spatial_coverage_description: Optional[LanguageStringType] = Field(
        None,
        description="Description of the data set's spatial coverage",
        title="Spatial coverage description",
    )
    use_restrictions: Optional[list[UseRestrictionItem]] = Field(
        None,
        description="Any usage restrictions and usage restriction dates for the dataset, for example a deadline (date) for when the dataset should be deleted/anonymized.",
        title="Use restriction",
    )
    custom_type: Optional[list[CustomTypeForDatasetMetadatum]] = Field(
        None,
        description="Extend the DataDoc model by adding custom metadata elements as key-value-pairs (string, array or objects).",
        title="Custom type for dataset metadata",
    )
    id: Optional[UUID] = Field(
        None, description="Unique identifier for the data set", title="Identifier"
    )
    owner: Optional[str] = Field(
        None,
        description="Owner of the data set (responsible division in Statistics Norway). Values defined by https://www.ssb.no/en/klass/klassifikasjoner/83",
        title="Owner",
    )
    file_path: Optional[str] = Field(
        None,
        description="The file path contains the data set's name and the path to where it is stored",
        title="File path",
    )
    metadata_created_date: Optional[AwareDatetime] = Field(
        None,
        description="Created date for metadata about the data set",
        title="Metadata created date",
    )
    metadata_created_by: Optional[str] = Field(
        None, description="Created by identifiable person.", title="Metadata created by"
    )
    metadata_last_updated_date: Optional[AwareDatetime] = Field(
        None,
        description="Last updated date for metadata about the dataset",
        title="Metadata last updated date",
    )
    metadata_last_updated_by: Optional[str] = Field(
        None,
        description="Last change made by identifiable person. ",
        title="Metadata last updated by",
    )
    contains_data_from: Optional[date] = Field(
        None,
        description="The data set contains data from date/time",
        title="Contains data from",
    )
    contains_data_until: Optional[date] = Field(
        None,
        description="The data set contains data up until date/time",
        title="Contains data up until",
    )


class OtherSpecialValue(DatadocBaseModel):
    code: Optional[str] = Field(None, description="Other value code", title="Code")
    name: Optional[LanguageStringType] = Field(
        None, description="Other value name (text)", title="Name"
    )
    valid_from: Optional[AwareDatetime] = Field(
        None, description="Other value valid from date", title="Valid from"
    )
    valid_until: Optional[AwareDatetime] = Field(
        None, description="Other value until date", title="Valid until"
    )


class SpecialValues(DatadocBaseModel):
    sentinel: Optional[SentinelValues] = Field(None, title="Sentinel values")
    other_value: Optional[list[OtherSpecialValue]] = Field(
        None,
        description="Other special values not represented as 'sentinel_value' in a standardized code list.",
        title="Other special values",
    )


class Variable(DatadocBaseModel):
    short_name: Optional[str] = Field(
        None,
        description="Physical name of the variable (data element) in the dataset. Should match the recommended short name.",
        title="Short name",
    )
    data_element_path: Optional[str] = Field(
        None,
        description="The path (dot notation) to the data element in a hierarchical data structure, eg. 'person.adress'. Must be given in addition to the short_name.",
        title="Data element path",
    )
    name: Optional[LanguageStringType] = Field(
        None,
        description="Variable names can be inherited from VarDef, but can also be documented/changed here",
        title="Name",
    )
    data_type: Optional[DataType] = Field(
        None, description="Data type", title="Data type"
    )
    variable_role: Optional[VariableRole] = Field(
        None,
        description="Role of the instance variable in the data set",
        title="Variable role",
    )
    definition_uri: Optional[AnyUrl] = Field(
        None,
        description="A link (URI) to the variable's definition in Vardok/VarDef",
        title="Definition URI",
    )
    is_personal_data: Optional[bool] = Field(
        None,
        description="Whether or not the variable is personal data.",
        title="Is personal data",
    )
    pseudonymization: Optional[Pseudonymization] = Field(
        None, description="A pseudonymized variable in the dataset."
    )
    unit_type: Optional[str] = Field(
        None,
        description="Unit Type which this variable pertains to. Values shall be codes from https://www.ssb.no/klass/klassifikasjoner/702. See Definitions of Unit Types https://www.ssb.no/en/metadata/definisjoner-av-statistiske-enheter",
        title="Unit type",
    )
    data_source: Optional[str] = Field(
        None,
        description="The source of the data contained in this variable. Values shall be codes from https://www.ssb.no/klass/klassifikasjoner/712.",
        title="Data source",
    )
    population_description: Optional[LanguageStringType] = Field(
        None,
        description="The population the variable describes can be specified in more detail here. Set at dataset level, but can be overwritten at instance variable level.",
        title="Population description",
    )
    comment: Optional[LanguageStringType] = Field(
        None,
        description="Further clarification of the variables definition",
        title="Comment",
    )
    temporality_type: Optional[TemporalityTypeType] = Field(
        None, description="Temporality type of this variable.", title="Temporality type"
    )
    measurement_unit: Optional[str] = Field(
        None, description="Measurement unit", title="Measurement unit"
    )
    multiplication_factor: Optional[int] = Field(
        None,
        description="A multiplication factor for a value/result is a number that multiplies that value/result.",
        title="Multiplication factor",
    )
    format: Optional[str] = Field(
        None,
        description="The format of the values \u200b\u200b(physical format or regular expression) in machine-readable form for validation. This can be used as a further specification of the data type (dataType) in those cases where this is relevant.",
        title="Format",
    )
    classification_uri: Optional[AnyUrl] = Field(
        None,
        description="Link (URI) to valid classification or code list",
        title="Classification or codelist URI",
    )
    special_value: Optional[SpecialValues] = Field(None, title="Special values")
    invalid_value_description: Optional[LanguageStringType] = Field(
        None,
        description="Invalid value(s) description used in addition (or as an alternative) to standard sentinel values.",
        title="Invalid value(s) description",
    )
    custom_type: Optional[list[CustomTypeForVariableMetadatum]] = Field(
        None,
        description="Extend the DataDoc model by adding custom metadata elements as key-value-pairs (string, array or objects).",
        title="Custom type for variable metadata",
    )
    id: Optional[UUID] = Field(
        None,
        description="Unique SSB identifier for the instance variable in the data set",
        title="Identifier",
    )
    contains_data_from: Optional[date] = Field(
        None,
        description="The instance variable in the data set contains data from and including this date. This can be useful information for data sets that contain many instance variables in addition to data for many periods/years. In many cases, it will then be the case that some variables only contain data for the most recent periods/years, e.g. if the entire data set contains data from 1970 to 2020, while some instance variables only contain data from 1998 onwards.",
        title="Contains data from",
    )
    contains_data_until: Optional[date] = Field(
        None,
        description="The instance variable in the data set contains data up to and including this date. This can be useful information for data sets that contain many instance variables in addition to data for many periods/years. In many cases, it will then be the case that some of the instance variables in the data set are terminated (no longer updated) after a given point in time.",
        title="Contains data up until",
    )


class DatadocMetadata(DatadocBaseModel):
    percentage_complete: Optional[int] = Field(
        None, description="Percentage of obligatory metadata fields populated."
    )
    document_version: Literal["6.1.0"] = Field(
        "6.1.0", description="Version of this model"
    )
    dataset: Optional[Dataset] = None
    variables: Optional[list[Variable]] = None


class MetadataContainer(DatadocBaseModel):
    document_version: Literal["1.0.0"] = "1.0.0"
    datadoc: Optional[DatadocMetadata] = None
