from __future__ import annotations

import json
from typing import Any

from xfintech.serde.common.dataformat import DataFormat
from xfintech.serde.common.deserialiserlike import DeserialiserLike
from xfintech.serde.common.error import (
    DeserialiserFailedError,
    DeserialiserInputTypeError,
    DeserialiserNotSupportedError,
)


class PythonDeserialiser(DeserialiserLike):
    """
    描述:
    - PythonDict反序列化模块。
    - BYTES -> DICT 的单向转换，适用于配置和轻量级数据交换。

    方法:
    - deserialise(data, format, **kwargs): 通用反序列化方法，仅支持 JSON 格式。
    - from_json(data,  **kwargs): 从 JSON 字节流解码为数据，编码默认 "utf-8"。

    例子:
    ```python
        from xfintech.serde.deserialiser.python import PythonDeserialiser
        from xfintech.serde.common.dataformat import DataFormat

        # 使用通用反序列化方法（推荐）
        data = PythonDeserialiser.deserialise(
            json_bytes,
            format=DataFormat.JSON,
        )
    ```
    """

    @staticmethod
    def deserialise(
        data: bytes,
        format: DataFormat | str,
        **kwargs: Any,
    ) -> Any:
        if not isinstance(data, bytes):
            msg = f"PythonDeserialiser.deserialise expects bytes, got {type(data)}"
            raise DeserialiserInputTypeError(msg)
        format = DataFormat.from_any(format)
        if format == DataFormat.JSON:
            return PythonDeserialiser.from_json(data, **kwargs)
        else:
            msg = f"Unsupported DataFormat for deserialization: {format}"
            raise DeserialiserNotSupportedError(msg)

    @staticmethod
    def from_json(
        data: bytes,
        **kwargs: Any,
    ) -> Any:
        encoding = kwargs.pop("encoding", "utf-8")
        payload = data.decode(encoding)
        try:
            return json.loads(
                payload,
                **kwargs,
            )
        except Exception as e:
            msg = f"Failed to deserialize data: {e}"
            raise DeserialiserFailedError(msg) from e
