# Copyright (C) 2020-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.

"""
HERE Platform Schema module

A schema contains the protobuf parsed schema and provides helper methods for
working with the schema and decoding data to a protobuf ``Message`` or Python ``Dict``.
"""

import webbrowser
from typing import Dict, List

from deprecated.sphinx import deprecated
from google.protobuf.json_format import MessageToDict
from google.protobuf.message import Message
from here.platform.config import PlatformConfig
from here.platform.schema import ProtobufParser


class Schema:
    """A protobuf schema registered on the HERE platform."""

    def __init__(self, schema_hrn: str, parser: ProtobufParser, platform_config: PlatformConfig):
        """Instantiate a Schema with HRN and parser."""
        self.schema_hrn = schema_hrn
        self.parser = parser
        self._platform_config = platform_config

    @property
    def supported_content_types(self) -> List[str]:
        """The content types this schema describes."""
        return ["application/protobuf", "application/x-protobuf"]

    def decode_blob(self, data: bytes) -> Message:
        """
        Decode a protobuf-encoded blob and returns
        the corresponding partition main message.

        :param data: encoded protobuf content
        :return: decoded protobuf message
        """
        return self.parser.parse_message(data)

    @deprecated(
        version="2.5", reason="Please call decode_blob and parse the result using MessageToDict"
    )
    def decode_and_parse_blob(self, data: bytes) -> Dict:
        """
        Decode a protobuf-encoded blob and parse the corresponding
        partition main message into a Python dictionary,
        conforming to the proto3 JSON spec with default settings.

        :param data: encoded protobuf content
        :return: decoded and parsed Python dictionary
        """
        return MessageToDict(self.parser.parse_message(data))

    @staticmethod
    @deprecated(version="2.5", reason="Please use MessageToDict to parse")
    def to_dict(decoded_blob: Message) -> Dict:
        """
        Parse a protobuf message into a Python dictionary,
        conforming to the proto3 JSON spec with default settings.

        :param decoded_blob: decoded protobuf message
        :return: parsed Python dictionary
        """
        return MessageToDict(decoded_blob)

    def open_in_portal(self):
        """Open the schema page on the HERE platform portal."""
        portal_url = self._platform_config.portal_url
        if portal_url is None:
            raise ValueError("here_platform_portal_url is not present in configuration.")
        webbrowser.open_new(f"{portal_url}/data/schemas/{self.schema_hrn}")
