# generated by datamodel-codegen:
#   filename:  lcax.schema.json

from __future__ import annotations

from datetime import date
from enum import Enum
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, ConfigDict, Field


class BuildingModelScope(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    building_services: bool
    external_works: bool
    facilitating_works: bool
    ff_e: bool
    finishes: bool
    substructure: bool
    superstructure_envelope: bool
    superstructure_frame: bool
    superstructure_internal_elements: bool


class BuildingType(Enum):
    RENOVATION = 'renovation'
    NEW = 'new'


class BuildingTypology(Enum):
    OFFICE = 'office'
    RESIDENTIAL = 'residential'
    PUBLIC = 'public'
    COMMERCIAL = 'commercial'
    INDUSTRIAL = 'industrial'
    INFRASTRUCTURE = 'infrastructure'
    AGRICULTURAL = 'agricultural'
    MIXEDUSE = 'mixeduse'
    OTHER = 'other'


class Classification(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    code: str
    name: str
    system: str


class Country(Enum):
    UNKNOWN = 'unknown'
    AFG = 'afg'
    ALA = 'ala'
    ALB = 'alb'
    DZA = 'dza'
    ASM = 'asm'
    AND_ = 'and'
    AGO = 'ago'
    AIA = 'aia'
    ATA = 'ata'
    ATG = 'atg'
    ARG = 'arg'
    ARM = 'arm'
    ABW = 'abw'
    AUS = 'aus'
    AUT = 'aut'
    AZE = 'aze'
    BHS = 'bhs'
    BHR = 'bhr'
    BGD = 'bgd'
    BRB = 'brb'
    BLR = 'blr'
    BEL = 'bel'
    BLZ = 'blz'
    BEN = 'ben'
    BMU = 'bmu'
    BTN = 'btn'
    BOL = 'bol'
    BES = 'bes'
    BIH = 'bih'
    BWA = 'bwa'
    BVT = 'bvt'
    BRA = 'bra'
    IOT = 'iot'
    BRN = 'brn'
    BGR = 'bgr'
    BFA = 'bfa'
    BDI = 'bdi'
    CPV = 'cpv'
    KHM = 'khm'
    CMR = 'cmr'
    CAN = 'can'
    CYM = 'cym'
    CAF = 'caf'
    TCD = 'tcd'
    CHL = 'chl'
    CHN = 'chn'
    CXR = 'cxr'
    CCK = 'cck'
    COL = 'col'
    COM = 'com'
    COG = 'cog'
    COD = 'cod'
    COK = 'cok'
    CRI = 'cri'
    CIV = 'civ'
    HRV = 'hrv'
    CUB = 'cub'
    CUW = 'cuw'
    CYP = 'cyp'
    CZE = 'cze'
    DNK = 'dnk'
    DJI = 'dji'
    DMA = 'dma'
    DOM = 'dom'
    ECU = 'ecu'
    EGY = 'egy'
    SLV = 'slv'
    GNQ = 'gnq'
    ERI = 'eri'
    EST = 'est'
    SWZ = 'swz'
    ETH = 'eth'
    FLK = 'flk'
    FRO = 'fro'
    FJI = 'fji'
    FIN = 'fin'
    FRA = 'fra'
    GUF = 'guf'
    PYF = 'pyf'
    ATF = 'atf'
    GAB = 'gab'
    GMB = 'gmb'
    GEO = 'geo'
    DEU = 'deu'
    GHA = 'gha'
    GIB = 'gib'
    GRC = 'grc'
    GRL = 'grl'
    GRD = 'grd'
    GLP = 'glp'
    GUM = 'gum'
    GTM = 'gtm'
    GGY = 'ggy'
    GIN = 'gin'
    GNB = 'gnb'
    GUY = 'guy'
    HTI = 'hti'
    HMD = 'hmd'
    VAT = 'vat'
    HND = 'hnd'
    HKG = 'hkg'
    HUN = 'hun'
    ISL = 'isl'
    IND = 'ind'
    IDN = 'idn'
    IRN = 'irn'
    IRQ = 'irq'
    IRL = 'irl'
    IMN = 'imn'
    ISR = 'isr'
    ITA = 'ita'
    JAM = 'jam'
    JPN = 'jpn'
    JEY = 'jey'
    JOR = 'jor'
    KAZ = 'kaz'
    KEN = 'ken'
    KIR = 'kir'
    PRK = 'prk'
    KOR = 'kor'
    KWT = 'kwt'
    KGZ = 'kgz'
    LAO = 'lao'
    LVA = 'lva'
    LBN = 'lbn'
    LSO = 'lso'
    LBR = 'lbr'
    LBY = 'lby'
    LIE = 'lie'
    LTU = 'ltu'
    LUX = 'lux'
    MAC = 'mac'
    MDG = 'mdg'
    MWI = 'mwi'
    MYS = 'mys'
    MDV = 'mdv'
    MLI = 'mli'
    MLT = 'mlt'
    MHL = 'mhl'
    MTQ = 'mtq'
    MRT = 'mrt'
    MUS = 'mus'
    MYT = 'myt'
    MEX = 'mex'
    FSM = 'fsm'
    MDA = 'mda'
    MCO = 'mco'
    MNG = 'mng'
    MNE = 'mne'
    MSR = 'msr'
    MAR = 'mar'
    MOZ = 'moz'
    MMR = 'mmr'
    NAM = 'nam'
    NRU = 'nru'
    NPL = 'npl'
    NLD = 'nld'
    NCL = 'ncl'
    NZL = 'nzl'
    NIC = 'nic'
    NER = 'ner'
    NGA = 'nga'
    NIU = 'niu'
    NFK = 'nfk'
    MKD = 'mkd'
    MNP = 'mnp'
    NOR = 'nor'
    OMN = 'omn'
    PAK = 'pak'
    PLW = 'plw'
    PSE = 'pse'
    PAN = 'pan'
    PNG = 'png'
    PRY = 'pry'
    PER = 'per'
    PHL = 'phl'
    PCN = 'pcn'
    POL = 'pol'
    PRT = 'prt'
    PRI = 'pri'
    QAT = 'qat'
    REU = 'reu'
    ROU = 'rou'
    RUS = 'rus'
    RWA = 'rwa'
    BLM = 'blm'
    SHN = 'shn'
    KNA = 'kna'
    LCA = 'lca'
    MAF = 'maf'
    SPM = 'spm'
    VCT = 'vct'
    WSM = 'wsm'
    SMR = 'smr'
    STP = 'stp'
    SAU = 'sau'
    SEN = 'sen'
    SRB = 'srb'
    SYC = 'syc'
    SLE = 'sle'
    SGP = 'sgp'
    SXM = 'sxm'
    SVK = 'svk'
    SVN = 'svn'
    SLB = 'slb'
    SOM = 'som'
    ZAF = 'zaf'
    SGS = 'sgs'
    SSD = 'ssd'
    ESP = 'esp'
    LKA = 'lka'
    SDN = 'sdn'
    SUR = 'sur'
    SJM = 'sjm'
    SWE = 'swe'
    CHE = 'che'
    SYR = 'syr'
    TWN = 'twn'
    TJK = 'tjk'
    TZA = 'tza'
    THA = 'tha'
    TLS = 'tls'
    TGO = 'tgo'
    TKL = 'tkl'
    TON = 'ton'
    TTO = 'tto'
    TUN = 'tun'
    TUR = 'tur'
    TKM = 'tkm'
    TCA = 'tca'
    TUV = 'tuv'
    UGA = 'uga'
    UKR = 'ukr'
    ARE = 'are'
    GBR = 'gbr'
    USA = 'usa'
    UMI = 'umi'
    URY = 'ury'
    UZB = 'uzb'
    VUT = 'vut'
    VEN = 'ven'
    VNM = 'vnm'
    VGB = 'vgb'
    VIR = 'vir'
    WLF = 'wlf'
    ESH = 'esh'
    YEM = 'yem'
    ZMB = 'zmb'
    ZWE = 'zwe'


class ExternalImpactData(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    format: str
    url: str
    version: Optional[str] = None


class GeneralEnergyClass(Enum):
    EXISTING = 'existing'
    STANDARD = 'standard'
    ADVANCED = 'advanced'
    UNKNOWN = 'unknown'


class ImpactCategoryKey(Enum):
    GWP = 'gwp'
    GWP_FOS = 'gwp_fos'
    GWP_BIO = 'gwp_bio'
    GWP_LUL = 'gwp_lul'
    ODP = 'odp'
    AP = 'ap'
    EP = 'ep'
    EP_FW = 'ep_fw'
    EP_MAR = 'ep_mar'
    EP_TER = 'ep_ter'
    POCP = 'pocp'
    ADPE = 'adpe'
    ADPF = 'adpf'
    PENRE = 'penre'
    PERE = 'pere'
    PERM = 'perm'
    PERT = 'pert'
    PENRT = 'penrt'
    PENRM = 'penrm'
    SM = 'sm'
    PM = 'pm'
    WDP = 'wdp'
    IRP = 'irp'
    ETP_FW = 'etp_fw'
    HTP_C = 'htp_c'
    HTP_NC = 'htp_nc'
    SQP = 'sqp'
    RSF = 'rsf'
    NRSF = 'nrsf'
    FW = 'fw'
    HWD = 'hwd'
    NHWD = 'nhwd'
    RWD = 'rwd'
    CRU = 'cru'
    MRF = 'mrf'
    MER = 'mer'
    EEE = 'eee'
    EET = 'eet'


class ImpactDataSource3(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
        populate_by_name=True,
    )
    externalimpactdata: ExternalImpactData


class InternalImpactData(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    path: str


class LifeCycleStage(Enum):
    A1A3 = 'a1a3'
    A4 = 'a4'
    A5 = 'a5'
    B1 = 'b1'
    B2 = 'b2'
    B3 = 'b3'
    B4 = 'b4'
    B5 = 'b5'
    B6 = 'b6'
    B7 = 'b7'
    C1 = 'c1'
    C2 = 'c2'
    C3 = 'c3'
    C4 = 'c4'
    D = 'd'


class Location(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    address: Optional[str] = None
    city: Optional[str] = None
    country: Country


class ProjectInfo2(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
        populate_by_name=True,
    )
    infrastructureinfo: Dict[str, str]


class ProjectPhase(Enum):
    DESIGN = 'design'
    ONGOING = 'ongoing'
    BUILT = 'built'
    OTHER = 'other'


class RoofType(Enum):
    FLAT = 'flat'
    PITCHED = 'pitched'
    SADDLE = 'saddle'
    PYRAMID = 'pyramid'
    OTHER = 'other'


class SoftwareInfo(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    calculation_type: Optional[str] = Field(None, alias='calculationType')
    goal_and_scope_definition: Optional[str] = Field(
        None, alias='goalAndScopeDefinition'
    )
    lca_software: str = Field(..., alias='lcaSoftware')


class Source(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    name: str
    url: Optional[str] = None


class Standard(Enum):
    EN15804_A1 = 'EN15804A1'
    EN15804_A2 = 'EN15804A2'
    UNKNOWN = 'UNKNOWN'


class SubType(Enum):
    GENERIC = 'Generic'
    SPECIFIC = 'Specific'
    INDUSTRY = 'Industry'
    REPRESENTATIVE = 'Representative'


class Unit(Enum):
    M = 'M'
    M2 = 'M2'
    M3 = 'M3'
    KG = 'KG'
    TONES = 'TONES'
    PCS = 'PCS'
    L = 'L'
    M2_R1 = 'M2R1'
    KM = 'KM'
    TONES_KM = 'TONES_KM'
    UNKNOWN = 'UNKNOWN'


class ValueUnit(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    unit: Unit
    value: float


class AreaType(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    definition: str
    unit: Unit
    value: float


class BuildingInfo(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    building_completion_year: Optional[int] = Field(
        None, alias='buildingCompletionYear', ge=0
    )
    building_footprint: Optional[ValueUnit] = Field(None, alias='buildingFootprint')
    building_height: Optional[ValueUnit] = Field(None, alias='buildingHeight')
    building_mass: Optional[ValueUnit] = Field(None, alias='buildingMass')
    building_model_scope: Optional[BuildingModelScope] = Field(
        None, alias='buildingModelScope'
    )
    building_permit_year: Optional[int] = Field(None, alias='buildingPermitYear', ge=0)
    building_type: BuildingType = Field(..., alias='buildingType')
    building_typology: BuildingTypology = Field(..., alias='buildingTypology')
    building_users: Optional[int] = Field(None, alias='buildingUsers', ge=0)
    certifications: Optional[List[str]] = None
    energy_demand_electricity: Optional[float] = Field(
        None, alias='energyDemandElectricity'
    )
    energy_demand_heating: Optional[float] = Field(None, alias='energyDemandHeating')
    energy_supply_electricity: Optional[float] = Field(
        None, alias='energySupplyElectricity'
    )
    energy_supply_heating: Optional[float] = Field(None, alias='energySupplyHeating')
    exported_electricity: Optional[float] = Field(None, alias='exportedElectricity')
    floors_above_ground: int = Field(..., alias='floorsAboveGround', ge=0)
    floors_below_ground: Optional[int] = Field(None, alias='floorsBelowGround', ge=0)
    frame_type: Optional[str] = Field(None, alias='frameType')
    general_energy_class: GeneralEnergyClass = Field(..., alias='generalEnergyClass')
    gross_floor_area: Optional[AreaType] = Field(None, alias='grossFloorArea')
    heated_floor_area: Optional[AreaType] = Field(None, alias='heatedFloorArea')
    local_energy_class: Optional[str] = Field(None, alias='localEnergyClass')
    roof_type: RoofType = Field(..., alias='roofType')


class Conversion(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    meta_data: str
    to: Unit
    value: float


class EPD(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    comment: Optional[str] = None
    conversions: Optional[List[Conversion]] = None
    declared_unit: Unit
    format_version: str
    id: str
    impacts: Dict[str, Dict[str, Optional[float]]]
    location: Country
    meta_data: Optional[Dict[str, Any]] = None
    name: str
    published_date: date
    reference_service_life: Optional[int] = Field(None, ge=0)
    source: Optional[Source] = None
    standard: Standard
    subtype: SubType
    valid_until: date
    version: str


class ImpactDataSource1(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
        populate_by_name=True,
    )
    epd: EPD


class ImpactDataSource4(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
        populate_by_name=True,
    )
    internalimpactdata: InternalImpactData


class ProjectInfo1(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
        populate_by_name=True,
    )
    buildinginfo: BuildingInfo


class TechFlow(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    comment: Optional[str] = None
    conversions: Optional[List[Conversion]] = None
    declared_unit: Unit
    format_version: str
    id: str
    impacts: Dict[str, Dict[str, Optional[float]]]
    location: Country
    meta_data: Optional[Dict[str, Any]] = None
    name: str
    source: Optional[Source] = None


class ImpactDataSource2(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
        populate_by_name=True,
    )
    techflow: TechFlow


class Transport(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    distance: float
    distance_unit: Unit = Field(..., alias='distanceUnit')
    id: str
    name: str
    transport_epd: Union[
        ImpactDataSource1, ImpactDataSource2, ImpactDataSource3, ImpactDataSource4
    ] = Field(..., alias='transportEpd')


class Product(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    description: Optional[str] = None
    id: str
    impact_data: Union[
        ImpactDataSource1, ImpactDataSource2, ImpactDataSource3, ImpactDataSource4
    ] = Field(..., alias='impactData')
    meta_data: Optional[Dict[str, Any]] = Field(None, alias='metaData')
    name: str
    quantity: float
    reference_service_life: int = Field(..., alias='referenceServiceLife', ge=0)
    results: Optional[Dict[str, Any]] = None
    transport: Optional[Transport] = None
    unit: Unit


class Assembly(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    category: Optional[str] = None
    classification: Optional[List[Classification]] = None
    comment: Optional[str] = None
    description: Optional[str] = None
    id: str
    meta_data: Optional[Dict[str, Any]] = Field(None, alias='metaData')
    name: str
    products: Dict[str, Product]
    quantity: float
    results: Optional[Dict[str, Any]] = None
    unit: Unit


class Project(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    assemblies: Dict[str, Assembly]
    classification_system: Optional[str] = Field(None, alias='classificationSystem')
    comment: Optional[str] = None
    description: Optional[str] = None
    format_version: str = Field(..., alias='formatVersion')
    id: str
    impact_categories: List[ImpactCategoryKey] = Field(..., alias='impactCategories')
    lcia_method: Optional[str] = Field(None, alias='lciaMethod')
    life_cycle_stages: List[LifeCycleStage] = Field(..., alias='lifeCycleStages')
    location: Location
    meta_data: Optional[Dict[str, Any]] = Field(None, alias='metaData')
    name: str
    owner: Optional[str] = None
    project_info: Optional[Union[ProjectInfo1, ProjectInfo2]] = Field(
        None, alias='projectInfo'
    )
    project_phase: ProjectPhase = Field(..., alias='projectPhase')
    reference_study_period: Optional[int] = Field(
        None, alias='referenceStudyPeriod', ge=0
    )
    results: Optional[Dict[str, Any]] = None
    software_info: SoftwareInfo = Field(..., alias='softwareInfo')
