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

from __future__ import annotations

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

from pydantic import BaseModel, Extra, Field


class BuildingModelScope(BaseModel):
    class Config:
        allow_population_by_field_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'
    other = 'other'


class Classification(BaseModel):
    class Config:
        allow_population_by_field_name = True

    code: str
    name: str
    system: str


class Country(Enum):
    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):
    class Config:
        allow_population_by_field_name = True

    format: str
    url: str
    version: Optional[str] = None


class GeneralEnergyClass(Enum):
    existing = 'existing'
    standard = 'standard'
    advanced = 'advanced'
    unknown = 'unknown'


class ImpactCategory(BaseModel):
    class Config:
        allow_population_by_field_name = True

    a1a3: Optional[float] = None
    a4: Optional[float] = None
    a5: Optional[float] = None
    b1: Optional[float] = None
    b2: Optional[float] = None
    b3: Optional[float] = None
    b4: Optional[float] = None
    b5: Optional[float] = None
    b6: Optional[float] = None
    b7: Optional[float] = None
    c1: Optional[float] = None
    c2: Optional[float] = None
    c3: Optional[float] = None
    c4: Optional[float] = None
    d: Optional[float] = None


class ImpactCategoryKey(Enum):
    gwp = 'gwp'
    odp = 'odp'
    ap = 'ap'
    ep = 'ep'
    pocp = 'pocp'
    adpe = 'adpe'
    adpf = 'adpf'
    penre = 'penre'
    pere = 'pere'
    perm = 'perm'
    pert = 'pert'
    penrt = 'penrt'
    penrm = 'penrm'
    sm = 'sm'
    rsf = 'rsf'
    nrsf = 'nrsf'
    fw = 'fw'
    hwd = 'hwd'
    nhwd = 'nhwd'
    rwd = 'rwd'
    cru = 'cru'
    mrf = 'mrf'
    mer = 'mer'
    eee = 'eee'
    eet = 'eet'


class ImpactDataSource2(BaseModel):
    class Config:
        extra = Extra.forbid
        allow_population_by_field_name = True

    externalimpactdata: ExternalImpactData


class InternalImpactData(BaseModel):
    class Config:
        allow_population_by_field_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):
    class Config:
        allow_population_by_field_name = True

    address: Optional[str] = None
    city: Optional[str] = None
    country: Country


class ProjectInfo2(BaseModel):
    class Config:
        extra = Extra.forbid
        allow_population_by_field_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):
    class Config:
        allow_population_by_field_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):
    class Config:
        allow_population_by_field_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):
    class Config:
        allow_population_by_field_name = True

    unit: Unit
    value: float


class AreaType(BaseModel):
    class Config:
        allow_population_by_field_name = True

    definition: str
    unit: Unit
    value: float


class BuildingInfo(BaseModel):
    class Config:
        allow_population_by_field_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):
    class Config:
        allow_population_by_field_name = True

    meta_data: str
    to: Unit
    value: float


class EPD(BaseModel):
    class Config:
        allow_population_by_field_name = True

    adpe: Optional[ImpactCategory] = None
    adpf: Optional[ImpactCategory] = None
    ap: Optional[ImpactCategory] = None
    comment: Optional[str] = None
    conversions: Optional[List[Conversion]] = None
    cru: Optional[ImpactCategory] = None
    declared_unit: Unit
    eee: Optional[ImpactCategory] = None
    eet: Optional[ImpactCategory] = None
    ep: Optional[ImpactCategory] = None
    format_version: str
    fw: Optional[ImpactCategory] = None
    gwp: Optional[ImpactCategory] = None
    hwd: Optional[ImpactCategory] = None
    id: str
    location: str
    mer: Optional[ImpactCategory] = None
    meta_data: Optional[Dict[str, Any]] = None
    mfr: Optional[ImpactCategory] = None
    name: str
    nhwd: Optional[ImpactCategory] = None
    nrsf: Optional[ImpactCategory] = None
    odp: Optional[ImpactCategory] = None
    penre: Optional[ImpactCategory] = None
    penrm: Optional[ImpactCategory] = None
    penrt: Optional[ImpactCategory] = None
    pere: Optional[ImpactCategory] = None
    perm: Optional[ImpactCategory] = None
    pert: Optional[ImpactCategory] = None
    pocp: Optional[ImpactCategory] = None
    published_date: datetime
    reference_service_life: Optional[int] = Field(None, ge=0)
    rsf: Optional[ImpactCategory] = None
    rwd: Optional[ImpactCategory] = None
    sm: Optional[ImpactCategory] = None
    source: Optional[Source] = None
    standard: Standard
    subtype: SubType
    valid_until: datetime
    version: str


class ImpactDataSource1(BaseModel):
    class Config:
        extra = Extra.forbid
        allow_population_by_field_name = True

    epd: EPD


class ImpactDataSource3(BaseModel):
    class Config:
        extra = Extra.forbid
        allow_population_by_field_name = True

    internalimpactdata: InternalImpactData


class ProjectInfo1(BaseModel):
    class Config:
        extra = Extra.forbid
        allow_population_by_field_name = True

    buildinginfo: BuildingInfo


class Transport(BaseModel):
    class Config:
        allow_population_by_field_name = True

    distance: float
    distance_unit: Unit = Field(..., alias='distanceUnit')
    id: str
    name: str
    transport_epd: Union[ImpactDataSource1, ImpactDataSource2, ImpactDataSource3] = (
        Field(..., alias='transportEpd')
    )


class Product(BaseModel):
    class Config:
        allow_population_by_field_name = True

    description: str
    id: str
    impact_data: Union[ImpactDataSource1, ImpactDataSource2, ImpactDataSource3] = 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):
    class Config:
        allow_population_by_field_name = True

    category: Optional[str] = None
    classification: Optional[List[Classification]] = None
    comment: Optional[str] = None
    description: str
    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 LCAxProject(BaseModel):
    class Config:
        allow_population_by_field_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')
