# Copyright (C) 2021-2022 HERE Global B.V. and its affiliate(s).
# All rights reserved.
#
# This software and other materials contain proprietary information
# controlled by HERE and are protected by applicable copyright legislation.
# Any use and utilization of this software and other materials and
# disclosure to any third parties is conditional upon having a separate
# agreement with HERE for the access, use, utilization or disclosure of this
# software. In the absence of such agreement, the use of the software is not
# allowed.

"""
Bindings for the HMC Rules & Regulations - Environmental Zones.
"""
from dataclasses import dataclass
from typing import List, Mapping

from google.protobuf.message import Message
from here.content.base import ContentIndexer, ContentPartition, SingleLayerBinding
from here.content.content import hmc_schema_version
from here.content.utils.proto import decode_message, parse_ref
from here.platform.adapter import DecodedMessage, Identifier, Ref


@dataclass
class Zone:
    """Environmental Zone"""

    identifier: Identifier
    name: List[DecodedMessage]
    info: DecodedMessage
    vehicle_class: List[DecodedMessage]
    environmental_badge: List[DecodedMessage]
    location_ref: List[Ref]

    indexer = ContentIndexer(identifier="identifier", refs={"location": "location_ref"})


class EnvironmentalZones(SingleLayerBinding):
    """
    Bindings for the HMC Rules & Regulations - Environmental Zones.
    """

    @classmethod
    def schema_hrn(cls) -> List[str]:
        """
        :return: the HRN of schema this binding can parse and index
        """
        return [
            f"hrn:here:schema:::com.here.schema.rib:env-zone-attributes_v2:{hmc_schema_version}"
        ]

    @classmethod
    def object_types(cls) -> Mapping[str, type]:
        """
        :return: the types of attributes supported by this binding
        """
        return {"zone": Zone}

    @classmethod
    def parse_and_index(cls, partition_id: str, msg: Message) -> ContentPartition:
        """
        Parse and index decoded message.

        :param partition_id: identifier of the partition
        :param msg: decoded content from the layer, in the form of a Protobuf message
        :return: the content of a partition parsed and indexed in its own data structure
        """
        assert hasattr(msg, "environmental_zone")

        zones = [
            Zone(
                identifier=Identifier(z.identifier),
                name=[decode_message(n) for n in z.name],
                info=decode_message(z.info),
                vehicle_class=[decode_message(n) for n in z.vehicle_class],
                environmental_badge=[decode_message(n) for n in z.environmental_badge],
                location_ref=[parse_ref(r) for r in z.location_ref],
            )
            for z in msg.environmental_zone  # type: ignore
        ]
        return ContentPartition(cls, zone=zones)
