class GatewayRuntimeException(GatewayException):
    """
    An exception that signifies a soap request went wrong.

    """

    soapfault = None
    """
    The soapfault that was generated by the service.
    """

    def __init__(self, message, soapfault):
        GatewayException.__init__(self, message)
        self.soapfault = soapfault class GatewayResourceNotFoundException(GatewayException):
    """
    An exception that signifies that no results where found.
    """
    def __init__(self):
        GatewayException.__init__(self, 'This resource was not found.') class Gewest(GatewayObject):
    """
    A large administrative unit in Belgium.

    Belgium consists of 3 `gewesten`. Together they form the entire territory
    of the country.
    """
    def __init__(
        self,
        id,
        namen=None,
        centroid=None,
        bounding_box=None,
        **kwargs
    ):
        self.id = int(id)
        self._namen = namen
        self._centroid = centroid
        self._bounding_box = bounding_box
        super().__init__(**kwargs)

    @property
    @check_lazy_load_gewest
    def naam(self):
        return self._namen['nl']

    @property
    @check_lazy_load_gewest
    def centroid(self):
        return self._centroid

    @property
    @check_lazy_load_gewest
    def bounding_box(self):
        return self._bounding_box

    @property
    def provincies(self):
        return self.gateway.list_provincies(self.id)

    @property
    def gemeenten(self):
        return self.gateway.list_gemeenten(self.id)

    def __unicode__(self):
        if self._namen is not None:
            return f"{self.naam} ({self.id})"
        else:
            return "Gewest %s" % (self.id)

    def __repr__(self):
        return "Gewest(%s)" % (self.id) class Provincie(GatewayObject):
    """
    The largest administrative unit within a :class:`Gewest`.

    .. versionadded:: 0.4.0
    """
    def __init__(
        self, niscode, naam, gewest, **kwargs
    ):
        self.id = self.niscode = int(niscode)
        self.naam = naam
        self.gewest = gewest

    def set_gateway(self, gateway):
        """
        :param crabpy.gateway.crab.CrabGateway gateway: Gateway to use.
        """
        self.gateway = gateway
        self.gewest.gateway = gateway

    def clear_gateway(self):
        """
        Clear the currently set CrabGateway.
        """
        self.gateway = None
        self.gewest.clear_gateway()

    @property
    def gemeenten(self):
        self.check_gateway()
        return self.gateway.list_gemeenten_by_provincie(self.niscode)

    def __unicode__(self):
        return f"{self.naam} ({self.niscode})"

    def __repr__(self):
        return f"Provincie({self.niscode}, '{self.naam}', Gewest({self.gewest.id}))" class Gemeente(GatewayObject):
    """
    The smallest administrative unit in Belgium.
    """
    def __init__(
            self, id, naam, niscode, gewest,
            taal=None, centroid=None,
            bounding_box=None, metadata=None, **kwargs
    ):
        self.id = int(id)
        self.naam = naam
        self.niscode = niscode
        self.gewest = gewest
        try:
            self._taal_id = taal.id
            self._taal = taal
        except AttributeError:
            self._taal_id = taal
            self._taal = None
        self._centroid = centroid
        self._bounding_box = bounding_box
        self._metadata = metadata
        super().__init__(**kwargs)

    def set_gateway(self, gateway):
        """
        :param crabpy.gateway.crab.CrabGateway gateway: Gateway to use.
        """
        self.gateway = gateway
        self.gewest.set_gateway(gateway)

    def clear_gateway(self):
        """
        Clear the currently set CrabGateway.
        """
        self.gateway = None
        self.gewest.clear_gateway()

    @property
    @check_lazy_load_gemeente
    def taal(self):
        if self._taal is None:
            talen = self.gateway.list_talen()
            for taal in talen:
                if taal.id == self._taal_id:
                    self._taal = taal
        return self._taal

    @property
    @check_lazy_load_gemeente
    def centroid(self):
        return self._centroid

    @property
    @check_lazy_load_gemeente
    def bounding_box(self):
        return self._bounding_box

    @property
    @check_lazy_load_gemeente
    def metadata(self):
        return self._metadata

    @property
    def straten(self):
        self.check_gateway()
        return self.gateway.list_straten(self)

    @property
    def postkantons(self):
        self.check_gateway()
        return self.gateway.list_postkantons_by_gemeente(self.id)

    @property
    def provincie(self):
        self.check_gateway()
        provincies = self.gateway.list_provincies(self.gewest)
        for p in provincies:
            if math.floor(self.niscode / 10000) == math.floor(p.niscode / 10000):
                return p

    def __unicode__(self):
        return f"{self.naam} ({self.id})"

    def __repr__(self):
        return f"Gemeente({self.id}, '{self.naam}', {self.niscode})" class Deelgemeente(GatewayObject):
    """
    A subdivision of a :class:`Gemeente`.

    .. versionadded:: 0.7.0
    """
    def __init__(
        self, id, naam, gemeente_niscode, **kwargs
    ):
        self.id = id
        self.naam = naam
        self.gemeente_niscode = gemeente_niscode

    def set_gateway(self, gateway):
        """
        :param crabpy.gateway.crab.CrabGateway gateway: Gateway to use.
        """
        self.gateway = gateway

    def clear_gateway(self):
        """
        Clear the currently set CrabGateway.
        """
        self.gateway = None

    @property
    def gemeente(self):
        return self.gateway.get_gemeente_by_niscode(self.gemeente_niscode)

    def __unicode__(self):
        return f"{self.naam} ({self.id})"

    def __repr__(self):
        return f"Deelgemeente('{self.id}', '{self.naam}', {self.gemeente_niscode})" class Taal(Codelijst):
    """
    A language.
    """
    def __repr__(self):
        return f"Taal('{self.id}', '{self.naam}', '{self.definitie}')" class Bewerking(Codelijst):
    """
    An edit.
    """
    def __repr__(self):
        return f"Bewerking({self.id}, '{self.naam}', '{self.definitie}')" class Organisatie(Codelijst):
    """
    An organisation that played a role in the genessis of an object.
    """
    def __repr__(self):
        return f"Organisatie({self.id}, '{self.naam}', '{self.definitie}')" class Aardsubadres(Codelijst):
    """
    The nature of a subaddress.
    """
    def __repr__(self):
        return f"Aardsubadres({self.id}, '{self.naam}', '{self.definitie}')" class Aardadres(Codelijst):
    """
    The nature of an address.
    """
    def __repr__(self):
        return f"Aardadres({self.id}, '{self.naam}', '{self.definitie}')" class Aardgebouw(Codelijst):
    """
    The nature of a building.
    """
    def __repr__(self):
        return f"Aardgebouw({self.id}, '{self.naam}', '{self.definitie}')" class Aardwegobject(Codelijst):
    """
    The nature of a `wegobject`.
    """
    def __repr__(self):
        return f"Aardwegobject({self.id}, '{self.naam}', '{self.definitie}')" class Aardterreinobject(Codelijst):
    """
    The nature of a `terreinobject`.
    """
    def __repr__(self):
        return f"Aardterreinobject({self.id}, '{self.naam}', '{self.definitie}')" class Statushuisnummer(Codelijst):
    """
    The current state of a `huisnummer`.
    """
    def __repr__(self):
        return f"Statushuisnummer({self.id}, '{self.naam}', '{self.definitie}')" class Statussubadres(Codelijst):
    """
    The current state of a `subadres`.
    """
    def __repr__(self):
        return f"Statussubadres({self.id}, '{self.naam}', '{self.definitie}')" class Statusstraatnaam(Codelijst):
    """
    The current state of a `straatnaam`.
    """
    def __repr__(self):
        return f"Statusstraatnaam({self.id}, '{self.naam}', '{self.definitie}')" class Statuswegsegment(Codelijst):
    """
    The current state of a `wegsegment`.
    """
    def __repr__(self):
        return f"Statuswegsegment({self.id}, '{self.naam}', '{self.definitie}')" class Geometriemethodewegsegment(Codelijst):
    """
    The geometry method of a :class:`Wegsegment`.
    """
    def __repr__(self):
        return f"Geometriemethodewegsegment({self.id}, '{self.naam}', '{self.definitie}')" class Statusgebouw(Codelijst):
    """
    The current state of a :class:`Gebouw`.
    """
    def __repr__(self):
        return f"Statusgebouw({self.id}, '{self.naam}', '{self.definitie}')" class Geometriemethodegebouw(Codelijst):
    """
    The geometry method of a :class:`Gebouw`.
    """
    def __repr__(self):
        return f"Geometriemethodegebouw({self.id}, '{self.naam}', '{self.definitie}')" class Herkomstadrespositie(Codelijst):
    """
    The origin of an Adressposition.
    """
    def __repr__(self):
        return f"Herkomstadrespositie({self.id}, '{self.naam}', '{self.definitie}')" class Straat(GatewayObject):
    """
    A street.

    A street object is always located in one and exactly one :class:`Gemeente`.
    """
    def __init__(
            self, id, label, gemeente_id, status,
            straatnaam, taalcode,
            straatnaam2, taalcode2,
            metadata=None, **kwargs
    ):
        self.id = id
        self.label = label
        try:
            self.status_id = status.id
            self._status = status
        except:
            self.status_id = status
            self._status = None
        self._namen = ((straatnaam, taalcode), (straatnaam2, taalcode2))
        self.gemeente_id = gemeente_id
        self._metadata = metadata
        super().__init__(**kwargs)

    @property
    def namen(self):
        return self._namen

    @property
    def gemeente(self):
        return self.gateway.get_gemeente_by_id(self.gemeente_id)

    @property
    def status(self):
        if self._status is None:
            res = self.gateway.list_statusstraatnamen()
            for status in res:
                if int(status.id) == int(self.status_id):
                    self._status = status
        return self._status

    @property
    @check_lazy_load_straat
    def metadata(self):
        return self._metadata

    @property
    def huisnummers(self):
        self.check_gateway()
        return self.gateway.list_huisnummers_by_straat(self)

    @property
    @check_lazy_load_straat
    def taal(self):
        return self.gemeente.taal

    @property
    def wegobjecten(self):
        self.check_gateway()
        return self.gateway.list_wegobjecten_by_straat(self)

    @property
    def wegsegmenten(self):
        self.check_gateway()
        return self.gateway.list_wegsegmenten_by_straat(self)

    @property
    def bounding_box(self):
        weg = [x.geometrie for x in self.wegsegmenten]
        if weg == []:
            return None
        x = []
        y = []
        for a in weg:
            a = a.replace("LINESTRING (", "").replace(")", "")
            list = a.split(',')
            for z in list:
                temp = z.split()
                x.append(float(temp[0]))
                y.append(float(temp[1]))
        return [min(x), min(y), max(x), max(y)]

    def __unicode__(self):
        return f"{self.label} ({self.id})"

    def __repr__(self):
        return f"Straat({self.id}, '{self.label}', {self.gemeente_id}, {self.status_id})" class Huisnummer(GatewayObject):
    """
    A house number.

    This is mainly a combination of a street and a house number.
    """
    def __init__(
            self, id, status, huisnummer, straat_id,
            metadata=None, **kwargs
    ):
        self.id = int(id)
        try:
            self.status_id = status.id
            self._status = status
        except AttributeError:
            self.status_id = status
            self._status = None
        self.huisnummer = huisnummer
        self.straat_id = straat_id
        self._metadata = metadata
        super().__init__(**kwargs)

    @property
    def straat(self):
        self.check_gateway()
        return self.gateway.get_straat_by_id(self.straat_id)

    @property
    @check_lazy_load_huisnummer
    def metadata(self):
        return self._metadata

    @property
    def status(self):
        if self._status is None:
            res = self.gateway.list_statushuisnummers()
            for status in res:
                if int(status.id) == int(self.status_id):
                    self._status = status
        return self._status

    @property
    def postkanton(self):
        self.check_gateway()
        return self.gateway.get_postkanton_by_huisnummer(self.id)

    @property
    def terreinobjecten(self):
        return self.gateway.list_terreinobjecten_by_huisnummer(self.id)

    @property
    def percelen(self):
        return self.gateway.list_percelen_by_huisnummer(self.id)

    @property
    def bounding_box(self):
        per = [x.bounding_box for x in self.terreinobjecten]
        if per == []:
            return None
        mini = min(per)
        maxi = max(per)
        return [mini[0], mini[1], maxi[0], maxi[1]]

    @property
    def postadres(self):
        self.check_gateway()
        return self.gateway.get_postadres_by_huisnummer(self.id)

    @property
    def gebouwen(self):
        self.check_gateway()
        return self.gateway.list_gebouwen_by_huisnummer(self.id)

    @property
    def subadressen(self):
        self.check_gateway()
        return self.gateway.list_subadressen_by_huisnummer(self.id)

    @property
    def adresposities(self):
        self.check_gateway()
        return self.gateway.list_adresposities_by_huisnummer(self.id)

    def __unicode__(self):
        return f"{self.huisnummer} ({self.id})"

    def __repr__(self):
        return f"Huisnummer({self.id}, {self.status_id}, '{self.huisnummer}', {self.straat_id})" class Postkanton(GatewayObject):
    """
    A postal code.

    Eg. postal code `9000` for the city of Ghent.
    """
    def __init__(self, id, **kwargs):
        self.id = int(id)
        super().__init__(**kwargs)

    def __unicode__(self):
        return "Postkanton %s" % (self.id)

    def __repr__(self):
        return "Postkanton(%s)" % (self.id) class Wegobject(GatewayObject):
    def __init__(
        self, id, aard, centroid=None,
        bounding_box=None, metadata=None, **kwargs
    ):
        self.id = id
        try:
            self.aard_id = aard.id
            self._aard = aard
        except AttributeError:
            self.aard_id = aard
            self._aard = None
        self._centroid = centroid
        self._bounding_box = bounding_box
        self._metadata = metadata
        super().__init__(**kwargs)

    @property
    def aard(self):
        if self._aard is None:
            res = self.gateway.list_aardwegobjecten()
            for aard in res:
                if int(aard.id) == int(self.aard_id):
                    self._aard = aard
        return self._aard

    @property
    @check_lazy_load_wegobject
    def centroid(self):
        return self._centroid

    @property
    @check_lazy_load_wegobject
    def bounding_box(self):
        return self._bounding_box

    @property
    @check_lazy_load_wegobject
    def metadata(self):
        return self._metadata

    def __unicode__(self):
        return "Wegobject %s" % (self.id)

    def __repr__(self):
        return "Wegobject(%s)" % (self.id) class Wegsegment(GatewayObject):
    def __init__(
        self, id, status, methode=None,
        geometrie=None, metadata=None, **kwargs
    ):
        self.id = id
        try:
            self.status_id = status.id
            self._status = status
        except:
            self.status_id = status
            self._status = None
        try:
            self._methode_id = methode.id
            self._methode = methode
        except:
            self._methode_id = methode
            self._methode = None
        self._geometrie = geometrie
        self._metadata = metadata
        super().__init__(**kwargs)

    @property
    def status(self):
        if self._status is None:
            res = self.gateway.list_statuswegsegmenten()
            for status in res:
                if int(status.id) == int(self.status_id):
                    self._status = status
        return self._status

    @property
    @check_lazy_load_wegsegment
    def methode(self):
        if self._methode is None:
            res = self.gateway.list_geometriemethodewegsegmenten()
            for methode in res:
                if int(methode.id) == int(self._methode_id):
                    self._methode = methode
        return self._methode

    @property
    @check_lazy_load_wegsegment
    def geometrie(self):
        return self._geometrie

    @property
    @check_lazy_load_wegsegment
    def metadata(self):
        return self._metadata

    def __unicode__(self):
        return "Wegsegment %s" % (self.id)

    def __repr__(self):
        return "Wegsegment(%s)" % (self.id) class Terreinobject(GatewayObject):
    """
    A cadastral parcel.

    A :class:`Terreinobject` is somewhat different from a :class:`Perceel`
    in the source of the data and the information provided. eg. A
    `terreinobject` has a `centroid` and a `bounding box`, while a `perceel`
    also has the centroid, but not the `bounding box`.
    """
    def __init__(
        self, id, aard, centroid=None,
        bounding_box=None, metadata=None, **kwargs
    ):
        self.id = id
        try:
            self.aard_id = aard.id
            self._aard = aard
        except AttributeError:
            self.aard_id = aard
            self._aard = None
        self._centroid = centroid
        self._metadata = metadata
        self._bounding_box = bounding_box
        super().__init__(**kwargs)

    @property
    def aard(self):
        if self._aard is None:
            res = self.gateway.list_aardterreinobjecten()
            for aard in res:
                if int(aard.id) == int(self.aard_id):
                    self._aard = aard
        return self._aard

    @property
    @check_lazy_load_terreinobject
    def centroid(self):
        return self._centroid

    @property
    @check_lazy_load_terreinobject
    def bounding_box(self):
        return self._bounding_box

    @property
    @check_lazy_load_terreinobject
    def metadata(self):
        return self._metadata

    def __unicode__(self):
        return "Terreinobject %s" % (self.id)

    def __repr__(self):
        return "Terreinobject(%s)" % (self.id) class Perceel(GatewayObject):
    """
    A cadastral Parcel.

    A :class:`Terreinobject` is somewhat different from a :class:`Perceel`
    in the source of the data and the information provided. eg. A
    `terreinobject` has a `centroid` and a `bounding box`, while a `perceel`
    also has the centroid, but not the `bounding box`.
    """
    def __init__(
        self, id, centroid=None, metadata=None, **kwargs
    ):
        self.id = id
        self._centroid = centroid
        self._metadata = metadata
        super().__init__(**kwargs)

    @property
    @check_lazy_load_perceel
    def centroid(self):
        return self._centroid

    @property
    @check_lazy_load_perceel
    def metadata(self):
        return self._metadata

    @property
    def huisnummers(self):
        """
        Returns the huisnummers on this Perceel.

        Some of the huisnummers might no longer be active.

        :rtype: list
        """
        self.check_gateway()
        return self.gateway.list_huisnummers_by_perceel(self.id)

    @property
    def postadressen(self):
        """
        Returns the postadressen for this Perceel.

        Will only take the huisnummers with status `inGebruik` into account.

        :rtype: list 
        """
        return [h.postadres for h in self.huisnummers if h.status.id == '3']

    def __unicode__(self):
        return "Perceel %s" % (self.id)

    def __repr__(self):
        return "Perceel(%s)" % (self.id) class Gebouw(GatewayObject):
    """
    A building.
    """
    def __init__(
        self, id, aard, status,
        methode=None, geometrie=None, metadata=None, **kwargs
    ):
        self.id = int(id)
        try:
            self.aard_id = aard.id
            self._aard = aard
        except:
            self.aard_id = aard
            self._aard = None
        try:
            self.status_id = status.id
            self._status = status
        except:
            self.status_id = status
            self._status = None
        try:
            self._methode_id = methode.id
            self._methode = methode
        except:
            self._methode_id = methode
            self._methode = None
        self._geometrie = geometrie
        self._metadata = metadata
        super().__init__(**kwargs)

    @property
    def aard(self):
        if self._aard is None:
            self.check_gateway()
            res = self.gateway.list_aardgebouwen()
            for aard in res:
                if int(aard.id) == int(self.aard_id):
                    self._aard = aard
        return self._aard

    @property
    def status(self):
        if self._status is None:
            self.check_gateway()
            res = self.gateway.list_statusgebouwen()
            for status in res:
                if int(status.id) == int(self.status_id):
                    self._status = status
        return self._status

    @property
    @check_lazy_load_gebouw
    def methode(self):
        if self._methode is None:
            res = self.gateway.list_geometriemethodegebouwen()
            for methode in res:
                if int(methode.id) == int(self._methode_id):
                    self._methode = methode
        return self._methode

    @property
    @check_lazy_load_gebouw
    def geometrie(self):
        return self._geometrie

    @property
    @check_lazy_load_gebouw
    def metadata(self):
        return self._metadata

    def __unicode__(self):
        return "Gebouw %s" % (self.id)

    def __repr__(self):
        return "Gebouw(%s)" % (self.id) class Metadata(GatewayObject):
    """
    Metadata about a `straat`, `huisnummer`, ...

    Some of the metadata available is the datum the object was created, the
    organisation that created it and the type of creation.
    """
    def __init__(
        self, begin_datum, begin_tijd,
        begin_bewerking, begin_organisatie,
        **kwargs
    ):
        self.begin_datum = str(begin_datum)
        self.begin_tijd = str(begin_tijd)
        try:
            self._begin_bewerking_id = begin_bewerking.id
            self._begin_bewerking = begin_bewerking
        except AttributeError:
            self._begin_bewerking_id = begin_bewerking
            self._begin_bewerking = None
        try:
            self._begin_organisatie_id = begin_organisatie.id
            self._begin_organisatie = begin_organisatie
        except AttributeError:
            self._begin_organisatie_id = begin_organisatie
            self._begin_organisatie = None
        super().__init__(**kwargs)

    @property
    def begin_bewerking(self):
        if self._begin_bewerking is None:
            self.check_gateway()
            bewerkingen = self.gateway.list_bewerkingen()
            for bewerking in bewerkingen:
                if int(bewerking.id) == int(self._begin_bewerking_id):
                    self._begin_bewerking = bewerking
        return self._begin_bewerking

    @property
    def begin_organisatie(self):
        if self._begin_organisatie is None:
            self.check_gateway()
            organisaties = self.gateway.list_organisaties()
            for organisatie in organisaties:
                if int(organisatie.id) == int(self._begin_organisatie_id):
                    self._begin_organisatie = organisatie
        return self._begin_organisatie

    def __unicode__(self):
        return "Begin datum: %s" % (self.begin_datum) class Subadres(GatewayObject):
    """
    An address within a certain :class:`Huisnummer`.

    These can eg. be postboxes within an appartment complex.
    """
    def __init__(
            self, id, subadres, status, huisnummer_id=None, aard=None,
            metadata=None, **kwargs
    ):
        self.id = int(id)
        self.subadres = subadres
        try:
            self.status_id = status.id
            self._status = status
        except AttributeError:
            self.status_id = status
            self._status = None
        self.huisnummer_id = huisnummer_id
        try:
            self.aard_id = aard.id
            self._aard = aard
        except AttributeError:
            self.aard_id = aard
            self._aard = None
        self._metadata = metadata
        super().__init__(**kwargs)

    @property
    def huisnummer(self):
        self.check_gateway()
        return self.gateway.get_huisnummer_by_id(self.huisnummer_id)

    @property
    @check_lazy_load_subadres
    def metadata(self):
        return self._metadata

    @property
    def status(self):
        if self._status is None:
            res = self.gateway.list_statushuisnummers()
            for status in res:
                if int(status.id) == int(self.status_id):
                    self._status = status
        return self._status

    @property
    @check_lazy_load_subadres
    def aard(self):
        if self._aard is None:
            res = self.gateway.list_aardsubadressen()
            for aard in res:
                if int(aard.id) == int(self.aard_id):
                    self._aard = aard
        return self._aard

    @property
    def postadres(self):
        self.check_gateway()
        return self.gateway.get_postadres_by_subadres(self.id)

    @property
    def adresposities(self):
        self.check_gateway()
        return self.gateway.list_adresposities_by_subadres(self.id)

    def __unicode__(self):
        return f"{self.subadres} ({self.id})"

    def __repr__(self):
        return f"Subadres({self.id}, {self.status_id}, '{self.subadres}', {self.huisnummer_id})" class Adrespositie(GatewayObject):
    """
    The position of an `Adres`.

    This can be used for the position of both :class:`Huisnummer` and
    :class:`Subadres`.

    A `Huisnummer` or `Subadres`, can have more than one `Adrespositie`, each
    offering a different interpretation of the position of the `Adres`. See
    the `herkomst` and `aard` of each `Adrespositie` to know which one to pick.
    """
    def __init__(
        self, id, herkomst, geometrie=None, aard=None,
        metadata=None, **kwargs
    ):
        self.id = id
        try:
            self.herkomst_id = herkomst.id
            self._herkomst = herkomst
        except AttributeError:
            self.herkomst_id = herkomst
            self._herkomst = None
        self._geometrie = geometrie
        try:
            self.aard_id = aard.id
            self._aard = aard
        except AttributeError:
            self.aard_id = aard
            self._aard = None
        self._metadata = metadata
        super().__init__(**kwargs)

    @property
    def herkomst(self):
        if self._herkomst is None:
            self.check_gateway()
            res = self.gateway.list_herkomstadresposities()
            for herkomst in res:
                if int(herkomst.id) == int(self.herkomst_id):
                    self._herkomst = herkomst
        return self._herkomst

    @property
    @check_lazy_load_adrespositie
    def metadata(self):
        return self._metadata

    @property
    @check_lazy_load_adrespositie
    def geometrie(self):
        return self._geometrie

    @property
    @check_lazy_load_adrespositie
    def aard(self):
        if self._aard is None:
            res = self.gateway.list_aardadressen()
            for aard in res:
                if int(aard.id) == int(self.aard_id):
                    self._aard = aard
        return self._aard

    def __unicode__(self):
        return "Adrespositie %s" % (self.id)

    def __repr__(self):
        return f"Adrespositie({self.id}, {self.herkomst_id})"
import six
import pytest
from unittest.mock import Mock
from crabpy.gateway.exception import (
    GatewayRuntimeException,
    GatewayResourceNotFoundException
)
from crabpy.gateway.crab import (
    Gewest, Provincie,
    Gemeente, Deelgemeente, Taal,
    Bewerking, Organisatie,
    Aardsubadres, Aardadres,
    Aardgebouw, Aardwegobject,
    Aardterreinobject, Statushuisnummer,
    Statussubadres, Statusstraatnaam,
    Statuswegsegment, Geometriemethodewegsegment,
    Statusgebouw, Geometriemethodegebouw,
    Herkomstadrespositie, Straat,
    Huisnummer, Postkanton,
    Wegobject, Wegsegment,
    Terreinobject, Perceel,
    Gebouw, Metadata, Subadres,
    Adrespositie
)
        )
        t = Terreinobject("13040_C_1747_G_002_00", 1)
        t.set_gateway(crab_gateway)
        assert isinstance(t.aard, Aardterreinobject)


class TestPerceel:
    def test_fully_initialised(self):
        p = Perceel(
            "13040C1747/00G002",
            (190708.59, 224667.59),
            Metadata(
                '1998-01-01 00:00:00',
                '2009-09-11 12:46:55.693000',
                Bewerking(3, '', ''),
                Organisatie(3, '', '')
            )
        )
        assert p.id == "13040C1747/00G002"
        assert p.centroid == (190708.59, 224667.59)
        assert isinstance(p.metadata, Metadata)
        assert p.metadata.begin_datum == '1998-01-01 00:00:00'
        assert p.metadata.begin_tijd == '2009-09-11 12:46:55.693000'
        assert isinstance(p.metadata.begin_bewerking, Bewerking)
        assert int(p.metadata.begin_bewerking.id) == 3
        assert isinstance(p.metadata.begin_organisatie, Organisatie)
        assert int(p.metadata.begin_organisatie.id) == 3
        assert 'Perceel 13040C1747/00G002' == str(p)
        assert 'Perceel(13040C1747/00G002)' == repr(p)

    def test_lazy_load(self, crab_gateway, crab_service):
        crab_service.GetPerceelByIdentificatorPerceel.return_value = Mock(
            IdentificatorPerceel='13040C1747/00G002',
            BeginBewerking=1, BeginOrganisatie=1, CenterX=190708.59,
            CenterY=224667.58,
        )
        p = Perceel("13040C1747/00G002")
        p.set_gateway(crab_gateway)
        assert p.id == "13040C1747/00G002"
        assert p.centroid == (190708.59, 224667.58)
        p.metadata.set_gateway(crab_gateway)
        assert isinstance(p.metadata, Metadata)
        assert p.metadata.begin_datum is not None
        assert p.metadata.begin_tijd is not None
        assert isinstance(p.metadata.begin_bewerking, Bewerking)
        assert int(p.metadata.begin_bewerking.id) == 1
        assert isinstance(p.metadata.begin_organisatie, Organisatie)
        assert int(p.metadata.begin_organisatie.id) == 1

    def test_huisnummers(self, crab_gateway, crab_service):
        crab_service.GetPerceelByIdentificatorPerceel.return_value = Mock(
            IdentificatorPerceel='13040C1747/00G002',
            BeginBewerking=1, BeginOrganisatie=1
        )
        crab_service.ListHuisnummersWithStatusByIdentificatorPerceel\
            .return_value = Mock(
                HuisnummerWithStatusItem=[Mock(HuisnummerId=1)]
            )
        crab_service.GetHuisnummerWithStatusByHuisnummerId.return_value = (
            Mock(HuisnummerId=1, BeginBewerking=1, BeginOrganisatie=1)
        )
        p = crab_gateway.get_perceel_by_id('13040C1747/00G002')
        hnrs = p.huisnummers
        assert isinstance(hnrs, list)
        assert [h.id for h in hnrs] == [h.id for h in crab_gateway.list_huisnummers_by_perceel('13040C1747/00G002')]

    def test_postadressen(self, crab_gateway, crab_service):
        crab_service.GetPerceelByIdentificatorPerceel.return_value = Mock(
            IdentificatorPerceel='13040C1747/00G002',
            BeginBewerking=1, BeginOrganisatie=1
        )
        crab_service.ListHuisnummersWithStatusByIdentificatorPerceel\
            .return_value = Mock(
                HuisnummerWithStatusItem=[Mock(HuisnummerId=1)]
            )
        crab_service.GetHuisnummerWithStatusByHuisnummerId.return_value = (
            Mock(HuisnummerId=1, BeginBewerking=1, BeginOrganisatie=1,
                 StatusHuisnummer=3)
        )
        crab_service.ListStatusHuisnummers.return_value = Mock(
            CodeItem=[Mock(Code='3')]
        )
        crab_service.GetPostadresByHuisnummerId.return_value = Mock(
            Postadres='Steenweg op Oosthoven 51, 2300 Turnhout'
        )
        p = crab_gateway.get_perceel_by_id('13040C1747/00G002')
        postadressen = p.postadressen
        assert isinstance(postadressen, list)
        assert ['Steenweg op Oosthoven 51, 2300 Turnhout'] == postadressen


class TestGebouw:
    def test_fully_initialised(self):
        g = Gebouw(
            "1538575",
            Aardgebouw(1, 'hoofdgebouw', 'hoofdgebouw volgens het GRB'),
            Statusgebouw(4, 'inGebruik', None),
            Geometriemethodegebouw(3, 'grb', None),
            """POLYGON ((190712.36432739347 224668.5216938965,\
 190706.26007138938 224667.54428589717,\
 190706.03594338894 224668.89276589826,\
 190704.89699938893 224668.66159789637,\
 190705.350887388 224666.14575789496,\
 190708.31754338741 224649.70287788659,\
 190717.16349539906 224653.81065388769,\
 190713.40490339696 224663.38582189381,\
 190712.36432739347 224668.5216938965))""",
            Metadata(
                '1830-01-01 00:00:00',
                '2011-05-19 10:51:09.483000',
                Bewerking(1, '', ''),
                Organisatie(5, '', '')
            )
        )
        assert g.id, 1538575
        assert int(g.aard_id) == 1
        assert isinstance(g.aard, Aardgebouw)
        assert int(g.status_id) == 4
        assert isinstance(g.status, Statusgebouw)
        assert int(g._methode_id) == 3

        assert isinstance(g.methode, Geometriemethodegebouw)