<commit_before># coding: utf-8

# This file is part of Navitia,
#     the software to build cool stuff with public transport.
#
# Hope you'll enjoy and contribute to this project,
#     powered by Canal TP (www.canaltp.fr).
# Help us simplify mobility and open public transport:
#     a non ending quest to the responsive locomotion way of traveling!
#
# LICENCE: This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Stay tuned using
# twitter @navitia
# channel `#navitia` on riot https://riot.im/app/#/room/#navitia:matrix.org
# https://groups.google.com/d/forum/navitia
# www.navitia.io

from __future__ import absolute_import, print_function, unicode_literals, division

from jormungandr.interfaces.v1.serializer import jsonschema, base
from jormungandr.interfaces.v1.serializer.pt import (
    PlaceSerializer,
    CalendarSerializer,
    VJDisplayInformationSerializer,
    StopDateTimeSerializer,
    StringListField,
    AccessPointSerializer,
)
from jormungandr.interfaces.v1.serializer.time import DateTimeField
from jormungandr.interfaces.v1.serializer.fields import (
    LinkSchema,
    RoundedField,
    SectionGeoJsonField,
    CoordSerializer,
)
from jormungandr.interfaces.v1.serializer.base import (
    AmountSerializer,
    PbNestedSerializer,
    EnumField,
    EnumListField,
    NestedEnumField,
    PbField,
    PbStrField,
    IntNestedPropertyField,
    PbIntField,
)
from flask import g
from navitiacommon.response_pb2 import (
    SectionAdditionalInformationType,
    GenderType,
    TransferType,
    StreetNetworkMode,
    SectionType,
)
from navitiacommon.type_pb2 import RTLevel
from jormungandr.interfaces.v1.make_links import create_internal_link


class CostSerializer(PbNestedSerializer):
    value = PbStrField(display_none=True)
    currency = PbField(schema_type=str)


class FareSerializer(PbNestedSerializer):
    found = jsonschema.BoolField()
    total = CostSerializer()
    links = jsonschema.MethodField(schema_type=LinkSchema(many=True), attr='ticket_id', display_none=True)

    def get_links(self, obj):
        if not hasattr(obj, 'ticket_id'):
            return []

        return [create_internal_link(id=value, rel='tickets', _type='ticket') for value in obj.ticket_id]

    # TODO check that retro compatibility is really useful
    def to_value(self, value):
        if value is None:
            return {'found': False, 'links': [], 'total': {'currency': '', 'value': '0.0'}}
        return super(FareSerializer, self).to_value(value)


class TicketSerializer(PbNestedSerializer):
    id = jsonschema.Field(schema_type=str, display_none=True, description='Identifier of the ticket')
    name = jsonschema.Field(schema_type=str, display_none=True, description='Name of the ticket')
    comment = jsonschema.Field(schema_type=str)
    found = jsonschema.BoolField()
    cost = CostSerializer(display_none=True)
    links = jsonschema.MethodField(schema_type=LinkSchema(many=True))
    source_id = jsonschema.Field(
        schema_type=str, display_none=True, description='Product identifier of the ticket in the input data'
    )

    def get_links(self, obj):
        if not hasattr(obj, 'section_id'):
            return None

        return [create_internal_link(id=value, rel='sections', _type='section') for value in obj.section_id]


class DurationsSerializer(PbNestedSerializer):
    total = jsonschema.Field(
        schema_type=int, display_none=True, description='Total duration of the journey (seconds)'
    )
    walking = jsonschema.Field(
        schema_type=int, display_none=True, description='Total walking duration of the journey (seconds)'
    )
    bike = jsonschema.Field(
        schema_type=int, display_none=True, description='Total duration by bike of the journey (seconds)'
    )
    car = jsonschema.Field(
        schema_type=int, display_none=True, description='Total duration by car of the journey (seconds)'
    )
    ridesharing = jsonschema.Field(
        schema_type=int, display_none=True, description='Total duration by ridesharing of the journey (seconds)'
    )
    taxi = jsonschema.Field(
        schema_type=int, display_none=True, description='Total duration by taxi of the journey (seconds)'
    )


class DistancesSerializer(PbNestedSerializer):
    walking = jsonschema.Field(
        schema_type=int, display_none=True, description='Total walking distance of the journey (meters)'
    )
    bike = jsonschema.Field(
        schema_type=int, display_none=True, description='Total distance by bike of the journey (meters)'
    )
    car = jsonschema.Field(
        schema_type=int, display_none=True, description='Total distance by car of the journey (meters)'
    )
    ridesharing = jsonschema.Field(
        schema_type=int, display_none=True, description='Total distance by ridesharing of the journey (meters)'
    )
    taxi = jsonschema.Field(
        schema_type=int, display_none=True, description='Total distance by taxi of the journey (meters)'
    )


class JourneyDebugSerializer(PbNestedSerializer):
    streetnetwork_duration = jsonschema.Field(
        schema_type=int,
        display_none=True,
        attr='sn_dur',
        description='Total duration of streetnetwork use (seconds)',
    )
    transfer_duration = jsonschema.Field(
        schema_type=int,
        display_none=True,
        attr='transfer_dur',
        description='Total duration of transfers (seconds)',
    )
    min_waiting_duration = jsonschema.Field(
        schema_type=int,
        display_none=True,
        attr='min_waiting_dur',
        description='Minimum on all waiting durations (seconds)',
    )
    nb_vj_extentions = jsonschema.Field(schema_type=int, display_none=True, description='Number of stay-in')
    nb_sections = jsonschema.Field(schema_type=int, display_none=True, description='Number of sections')
    internal_id = jsonschema.Field(schema_type=str, display_none=False)


class PathSerializer(PbNestedSerializer):
    id = jsonschema.MethodField(schema_type=int, display_none=False)
    length = RoundedField(display_none=True)
    name = jsonschema.Field(schema_type=str, display_none=True)
    duration = RoundedField(display_none=True)
    direction = jsonschema.Field(schema_type=int, display_none=True)
    instruction = jsonschema.MethodField(schema_type=str, display_none=False)
    instruction_start_coordinate = jsonschema.MethodField(schema_type=lambda: CoordSerializer())
    via_uri = jsonschema.MethodField(schema_type=str, display_none=False)

    def get_id(self, obj):
        if obj.HasField(str('id')):
            return obj.id
        else:
            return None

    def get_instruction(self, obj):
        if obj.HasField(str('instruction')):
            return obj.instruction
        else:
            return None

    def get_instruction_start_coordinate(self, obj):
        if obj.HasField(str('instruction_start_coordinate')):
            return CoordSerializer(obj.instruction_start_coordinate, display_none=False).data
        else:
            return None

    def get_via_uri(self, obj):
        return obj.via_uri if obj.HasField(str('via_uri')) else None


class ElevationSerializer(PbNestedSerializer):
    distance_from_start = RoundedField(display_none=True)
    elevation = RoundedField(display_none=True)
    geojson_index = RoundedField(display_none=True)


class SectionTypeEnum(EnumField):
    def as_getter(self, serializer_field_name, serializer_cls):
        def getter(value):
            # TODO, this should be done in kraken
            def if_on_demand_stop_time(stop):
                properties = stop.properties
                descriptor = properties.DESCRIPTOR
                enum = descriptor.enum_types_by_name["AdditionalInformation"]
                return any(
                    enum.values_by_number[v].name == 'on_demand_transport'
                    for v in properties.additional_informations
                )

            try:
                if value.stop_date_times:
                    first_stop = value.stop_date_times[0]
                    last_stop = value.stop_date_times[-1]
                    if if_on_demand_stop_time(first_stop):
                        return 'on_demand_transport'
                    elif if_on_demand_stop_time(last_stop):
                        return 'on_demand_transport'
                    return 'public_transport'
            except ValueError:
                pass
            attr = self.attr or serializer_field_name
            if value is None or not value.HasField(attr):
                return None
            enum = value.DESCRIPTOR.fields_by_name[attr].enum_type.values_by_number
            return enum[getattr(value, attr)].name

        return getter


class SeatsDescriptionSerializer(PbNestedSerializer):
    total = PbIntField(display_none=False)
    available = PbIntField(display_none=False)


class IndividualRatingSerializer(PbNestedSerializer):
    value = jsonschema.Field(schema_type=float, display_none=True)
    count = jsonschema.Field(schema_type=int, display_none=False)
    scale_min = jsonschema.Field(schema_type=float, display_none=False)
    scale_max = jsonschema.Field(schema_type=float, display_none=False)


class IndividualInformationSerializer(PbNestedSerializer):
    alias = jsonschema.Field(schema_type=str, display_none=True)
    image = jsonschema.Field(schema_type=str, display_none=False)
    gender = EnumField(attr='gender', pb_type=GenderType)
    rating = IndividualRatingSerializer(display_none=False)


class RidesharingInformationSerializer(PbNestedSerializer):
    operator = jsonschema.Field(schema_type=str, display_none=True)
    network = jsonschema.Field(schema_type=str, display_none=True)
    driver = IndividualInformationSerializer(display_none=False)
    seats = SeatsDescriptionSerializer(display_none=False)


class SectionSerializer(PbNestedSerializer):
    id = jsonschema.Field(schema_type=str, display_none=True)
    duration = jsonschema.Field(
        schema_type=int, display_none=True, description='Duration of the section (seconds)'
    )
    co2_emission = AmountSerializer(display_none=True)
    transfer_type = EnumField(attr='transfer_type', pb_type=TransferType)
    departure_date_time = DateTimeField(
        attr='begin_date_time', description='Departure date and time of the section'
    )
    arrival_date_time = DateTimeField(attr='end_date_time', description='Arrival date and time of the section')
    base_departure_date_time = DateTimeField(
        attr='base_begin_date_time', description='Base-schedule departure date and time of the section'
    )
    base_arrival_date_time = DateTimeField(
        attr='base_end_date_time', description='Base-schedule arrival date and time of the section'
    )
    data_freshness = EnumField(attr="realtime_level", pb_type=RTLevel, display_none=False)
    to = jsonschema.MethodField(schema_type=PlaceSerializer(), attr='destination')

    def get_to(self, obj):
        if obj.HasField(str('type')):
            enum = obj.DESCRIPTOR.fields_by_name['type'].enum_type.values_by_number
            ret_value = enum[getattr(obj, 'type')].name
            if ret_value == 'WAITING':
                return None
        return PlaceSerializer(obj.destination).data

    _from = jsonschema.MethodField(schema_type=PlaceSerializer(), attr='origin', label='from')

    def get__from(self, obj):
        if obj.HasField(str('type')):
            enum = obj.DESCRIPTOR.fields_by_name['type'].enum_type.values_by_number
            ret_value = enum[getattr(obj, 'type')].name
            if ret_value == 'WAITING':
                return None
        return PlaceSerializer(obj.origin).data

    additional_informations = EnumListField(
        attr='additional_informations', pb_type=SectionAdditionalInformationType
    )
    geojson = SectionGeoJsonField(display_none=False, description='GeoJSON of the shape of the section')
    mode = NestedEnumField(attr='street_network.mode', pb_type=StreetNetworkMode)
    type = SectionTypeEnum(attr='type', pb_type=SectionType)

    display_informations = VJDisplayInformationSerializer(attr='pt_display_informations', display_none=False)

    links = jsonschema.MethodField(display_none=True, schema_type=LinkSchema(many=True))

    def get_links(self, obj):
        response = []
        if obj.HasField(str("uris")):
            for type_, value in obj.uris.ListFields():
                response.append({"type": type_.name, "id": value})
        if obj.HasField(str('pt_display_informations')):
            response.extend(base.make_notes(obj.pt_display_informations.notes))
        if obj.HasField(str('ridesharing_information')):
            response.extend(
                [
                    {"type": "ridesharing_ad", "rel": l.key, "href": l.href, "internal": False}
                    for l in obj.ridesharing_information.links
                ]
            )

        return response

    stop_date_times = StopDateTimeSerializer(many=True)
    path = PathSerializer(attr="street_network.path_items", many=True, display_none=False)
    ridesharing_informations = RidesharingInformationSerializer(
        attr='ridesharing_information', display_none=False
    )
    ridesharing_journeys = jsonschema.MethodField(
        schema_type=lambda: JourneySerializer(display_none=False, many=True)
    )

    def get_ridesharing_journeys(self, obj):
        if not hasattr(obj, 'ridesharing_journeys') or not obj.ridesharing_journeys:
            return None
        return JourneySerializer(obj.ridesharing_journeys, display_none=False, many=True).data

    cycle_lane_length = PbIntField(display_none=False)
    elevations = ElevationSerializer(attr="street_network.elevations", many=True, display_none=False)
    vias = jsonschema.MethodField(many=True, display_none=False)

    def get_vias(self, obj):
        if not hasattr(obj, 'vias'):
            return None
        from navitiacommon import type_pb2

        pt_obejcts = [
            type_pb2.PtObject(name=ap.name, uri=ap.uri, embedded_type=type_pb2.ACCESS_POINT, access_point=ap)
            for ap in obj.vias
        ]
        return PlaceSerializer(pt_obejcts, display_none=False, many=True).data


class JourneySerializer(PbNestedSerializer):
    duration = jsonschema.Field(
        schema_type=int, display_none=True, description='Duration of the journey (seconds)'<commit_msg>fix schema test<commit_after># coding: utf-8

# This file is part of Navitia,
#     the software to build cool stuff with public transport.
#
# Hope you'll enjoy and contribute to this project,
#     powered by Canal TP (www.canaltp.fr).
# Help us simplify mobility and open public transport:
#     a non ending quest to the responsive locomotion way of traveling!
#
# LICENCE: This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Stay tuned using
# twitter @navitia
# channel `#navitia` on riot https://riot.im/app/#/room/#navitia:matrix.org
# https://groups.google.com/d/forum/navitia
# www.navitia.io

from __future__ import absolute_import, print_function, unicode_literals, division

from jormungandr.interfaces.v1.serializer import jsonschema, base
from jormungandr.interfaces.v1.serializer.pt import (
    PlaceSerializer,
    CalendarSerializer,
    VJDisplayInformationSerializer,
    StopDateTimeSerializer,
    StringListField,
    AccessPointSerializer,
)
from jormungandr.interfaces.v1.serializer.time import DateTimeField
from jormungandr.interfaces.v1.serializer.fields import (
    LinkSchema,
    RoundedField,
    SectionGeoJsonField,
    CoordSerializer,
)
from jormungandr.interfaces.v1.serializer.base import (
    AmountSerializer,
    PbNestedSerializer,
    EnumField,
    EnumListField,
    NestedEnumField,
    PbField,
    PbStrField,
    IntNestedPropertyField,
    PbIntField,
)
from flask import g
from navitiacommon.response_pb2 import (
    SectionAdditionalInformationType,
    GenderType,
    TransferType,
    StreetNetworkMode,
    SectionType,
)
from navitiacommon.type_pb2 import RTLevel
from jormungandr.interfaces.v1.make_links import create_internal_link


class CostSerializer(PbNestedSerializer):
    value = PbStrField(display_none=True)
    currency = PbField(schema_type=str)


class FareSerializer(PbNestedSerializer):
    found = jsonschema.BoolField()
    total = CostSerializer()
    links = jsonschema.MethodField(schema_type=LinkSchema(many=True), attr='ticket_id', display_none=True)

    def get_links(self, obj):
        if not hasattr(obj, 'ticket_id'):
            return []

        return [create_internal_link(id=value, rel='tickets', _type='ticket') for value in obj.ticket_id]

    # TODO check that retro compatibility is really useful
    def to_value(self, value):
        if value is None:
            return {'found': False, 'links': [], 'total': {'currency': '', 'value': '0.0'}}
        return super(FareSerializer, self).to_value(value)


class TicketSerializer(PbNestedSerializer):
    id = jsonschema.Field(schema_type=str, display_none=True, description='Identifier of the ticket')
    name = jsonschema.Field(schema_type=str, display_none=True, description='Name of the ticket')
    comment = jsonschema.Field(schema_type=str)
    found = jsonschema.BoolField()
    cost = CostSerializer(display_none=True)
    links = jsonschema.MethodField(schema_type=LinkSchema(many=True))
    source_id = jsonschema.Field(
        schema_type=str, display_none=True, description='Product identifier of the ticket in the input data'
    )

    def get_links(self, obj):
        if not hasattr(obj, 'section_id'):
            return None

        return [create_internal_link(id=value, rel='sections', _type='section') for value in obj.section_id]


class DurationsSerializer(PbNestedSerializer):
    total = jsonschema.Field(
        schema_type=int, display_none=True, description='Total duration of the journey (seconds)'
    )
    walking = jsonschema.Field(
        schema_type=int, display_none=True, description='Total walking duration of the journey (seconds)'
    )
    bike = jsonschema.Field(
        schema_type=int, display_none=True, description='Total duration by bike of the journey (seconds)'
    )
    car = jsonschema.Field(
        schema_type=int, display_none=True, description='Total duration by car of the journey (seconds)'
    )
    ridesharing = jsonschema.Field(
        schema_type=int, display_none=True, description='Total duration by ridesharing of the journey (seconds)'
    )
    taxi = jsonschema.Field(
        schema_type=int, display_none=True, description='Total duration by taxi of the journey (seconds)'
    )


class DistancesSerializer(PbNestedSerializer):
    walking = jsonschema.Field(
        schema_type=int, display_none=True, description='Total walking distance of the journey (meters)'
    )
    bike = jsonschema.Field(
        schema_type=int, display_none=True, description='Total distance by bike of the journey (meters)'
    )
    car = jsonschema.Field(
        schema_type=int, display_none=True, description='Total distance by car of the journey (meters)'
    )
    ridesharing = jsonschema.Field(
        schema_type=int, display_none=True, description='Total distance by ridesharing of the journey (meters)'
    )
    taxi = jsonschema.Field(
        schema_type=int, display_none=True, description='Total distance by taxi of the journey (meters)'
    )


class JourneyDebugSerializer(PbNestedSerializer):
    streetnetwork_duration = jsonschema.Field(
        schema_type=int,
        display_none=True,
        attr='sn_dur',
        description='Total duration of streetnetwork use (seconds)',
    )
    transfer_duration = jsonschema.Field(
        schema_type=int,
        display_none=True,
        attr='transfer_dur',
        description='Total duration of transfers (seconds)',
    )
    min_waiting_duration = jsonschema.Field(
        schema_type=int,
        display_none=True,
        attr='min_waiting_dur',
        description='Minimum on all waiting durations (seconds)',
    )
    nb_vj_extentions = jsonschema.Field(schema_type=int, display_none=True, description='Number of stay-in')
    nb_sections = jsonschema.Field(schema_type=int, display_none=True, description='Number of sections')
    internal_id = jsonschema.Field(schema_type=str, display_none=False)


class PathSerializer(PbNestedSerializer):
    id = jsonschema.MethodField(schema_type=int, display_none=False)
    length = RoundedField(display_none=True)
    name = jsonschema.Field(schema_type=str, display_none=True)
    duration = RoundedField(display_none=True)
    direction = jsonschema.Field(schema_type=int, display_none=True)
    instruction = jsonschema.MethodField(schema_type=str, display_none=False)
    instruction_start_coordinate = jsonschema.MethodField(schema_type=lambda: CoordSerializer())
    via_uri = jsonschema.MethodField(schema_type=str, display_none=False)

    def get_id(self, obj):
        if obj.HasField(str('id')):
            return obj.id
        else:
            return None

    def get_instruction(self, obj):
        if obj.HasField(str('instruction')):
            return obj.instruction
        else:
            return None

    def get_instruction_start_coordinate(self, obj):
        if obj.HasField(str('instruction_start_coordinate')):
            return CoordSerializer(obj.instruction_start_coordinate, display_none=False).data
        else:
            return None

    def get_via_uri(self, obj):
        return obj.via_uri if obj.HasField(str('via_uri')) else None


class ElevationSerializer(PbNestedSerializer):
    distance_from_start = RoundedField(display_none=True)
    elevation = RoundedField(display_none=True)
    geojson_index = RoundedField(display_none=True)


class SectionTypeEnum(EnumField):
    def as_getter(self, serializer_field_name, serializer_cls):
        def getter(value):
            # TODO, this should be done in kraken
            def if_on_demand_stop_time(stop):
                properties = stop.properties
                descriptor = properties.DESCRIPTOR
                enum = descriptor.enum_types_by_name["AdditionalInformation"]
                return any(
                    enum.values_by_number[v].name == 'on_demand_transport'
                    for v in properties.additional_informations
                )

            try:
                if value.stop_date_times:
                    first_stop = value.stop_date_times[0]
                    last_stop = value.stop_date_times[-1]
                    if if_on_demand_stop_time(first_stop):
                        return 'on_demand_transport'
                    elif if_on_demand_stop_time(last_stop):
                        return 'on_demand_transport'
                    return 'public_transport'
            except ValueError:
                pass
            attr = self.attr or serializer_field_name
            if value is None or not value.HasField(attr):
                return None
            enum = value.DESCRIPTOR.fields_by_name[attr].enum_type.values_by_number
            return enum[getattr(value, attr)].name

        return getter


class SeatsDescriptionSerializer(PbNestedSerializer):
    total = PbIntField(display_none=False)
    available = PbIntField(display_none=False)


class IndividualRatingSerializer(PbNestedSerializer):
    value = jsonschema.Field(schema_type=float, display_none=True)
    count = jsonschema.Field(schema_type=int, display_none=False)
    scale_min = jsonschema.Field(schema_type=float, display_none=False)
    scale_max = jsonschema.Field(schema_type=float, display_none=False)


class IndividualInformationSerializer(PbNestedSerializer):
    alias = jsonschema.Field(schema_type=str, display_none=True)
    image = jsonschema.Field(schema_type=str, display_none=False)
    gender = EnumField(attr='gender', pb_type=GenderType)
    rating = IndividualRatingSerializer(display_none=False)


class RidesharingInformationSerializer(PbNestedSerializer):
    operator = jsonschema.Field(schema_type=str, display_none=True)
    network = jsonschema.Field(schema_type=str, display_none=True)
    driver = IndividualInformationSerializer(display_none=False)
    seats = SeatsDescriptionSerializer(display_none=False)


class SectionSerializer(PbNestedSerializer):
    id = jsonschema.Field(schema_type=str, display_none=True)
    duration = jsonschema.Field(
        schema_type=int, display_none=True, description='Duration of the section (seconds)'
    )
    co2_emission = AmountSerializer(display_none=True)
    transfer_type = EnumField(attr='transfer_type', pb_type=TransferType)
    departure_date_time = DateTimeField(
        attr='begin_date_time', description='Departure date and time of the section'
    )
    arrival_date_time = DateTimeField(attr='end_date_time', description='Arrival date and time of the section')
    base_departure_date_time = DateTimeField(
        attr='base_begin_date_time', description='Base-schedule departure date and time of the section'
    )
    base_arrival_date_time = DateTimeField(
        attr='base_end_date_time', description='Base-schedule arrival date and time of the section'
    )
    data_freshness = EnumField(attr="realtime_level", pb_type=RTLevel, display_none=False)
    to = jsonschema.MethodField(schema_type=PlaceSerializer(), attr='destination')

    def get_to(self, obj):
        if obj.HasField(str('type')):
            enum = obj.DESCRIPTOR.fields_by_name['type'].enum_type.values_by_number
            ret_value = enum[getattr(obj, 'type')].name
            if ret_value == 'WAITING':
                return None
        return PlaceSerializer(obj.destination).data

    _from = jsonschema.MethodField(schema_type=PlaceSerializer(), attr='origin', label='from')

    def get__from(self, obj):
        if obj.HasField(str('type')):
            enum = obj.DESCRIPTOR.fields_by_name['type'].enum_type.values_by_number
            ret_value = enum[getattr(obj, 'type')].name
            if ret_value == 'WAITING':
                return None
        return PlaceSerializer(obj.origin).data

    additional_informations = EnumListField(
        attr='additional_informations', pb_type=SectionAdditionalInformationType
    )
    geojson = SectionGeoJsonField(display_none=False, description='GeoJSON of the shape of the section')
    mode = NestedEnumField(attr='street_network.mode', pb_type=StreetNetworkMode)
    type = SectionTypeEnum(attr='type', pb_type=SectionType)

    display_informations = VJDisplayInformationSerializer(attr='pt_display_informations', display_none=False)

    links = jsonschema.MethodField(display_none=True, schema_type=LinkSchema(many=True))

    def get_links(self, obj):
        response = []
        if obj.HasField(str("uris")):
            for type_, value in obj.uris.ListFields():
                response.append({"type": type_.name, "id": value})
        if obj.HasField(str('pt_display_informations')):
            response.extend(base.make_notes(obj.pt_display_informations.notes))
        if obj.HasField(str('ridesharing_information')):
            response.extend(
                [
                    {"type": "ridesharing_ad", "rel": l.key, "href": l.href, "internal": False}
                    for l in obj.ridesharing_information.links
                ]
            )

        return response

    stop_date_times = StopDateTimeSerializer(many=True)
    path = PathSerializer(attr="street_network.path_items", many=True, display_none=False)
    ridesharing_informations = RidesharingInformationSerializer(
        attr='ridesharing_information', display_none=False
    )
    ridesharing_journeys = jsonschema.MethodField(
        schema_type=lambda: JourneySerializer(display_none=False, many=True)
    )

    def get_ridesharing_journeys(self, obj):
        if not hasattr(obj, 'ridesharing_journeys') or not obj.ridesharing_journeys:
            return None
        return JourneySerializer(obj.ridesharing_journeys, display_none=False, many=True).data

    cycle_lane_length = PbIntField(display_none=False)
    elevations = ElevationSerializer(attr="street_network.elevations", many=True, display_none=False)
    vias = jsonschema.MethodField(schema_type=PlaceSerializer(), many=True, display_none=False)

    def get_vias(self, obj):
        if not hasattr(obj, 'vias'):
            return None
        from navitiacommon import type_pb2

        pt_obejcts = [
            type_pb2.PtObject(name=ap.name, uri=ap.uri, embedded_type=type_pb2.ACCESS_POINT, access_point=ap)
            for ap in obj.vias
        ]
        return PlaceSerializer(pt_obejcts, display_none=False, many=True).data


class JourneySerializer(PbNestedSerializer):
    duration = jsonschema.Field(
        schema_type=int, display_none=True, description='Duration of the journey (seconds)'
{'fraction_non_alphanumeric': 0.08892006547082205, 'fraction_numerical': 0.0012025253031365869, 'mean_word_length': 3.6272024729520864, 'pattern_counts': {'":': 12, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 4, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '678760', 'n_tokens_mistral': 8802, 'n_tokens_neox': 8629, 'n_words': 1906}