"""YAML parsing and dumping helpers based on ``ruamel.yaml``."""

from __future__ import annotations

from io import StringIO
from typing import Any

from ruamel.yaml import YAML
from ruamel.yaml.error import YAMLError as YamlError
from ruamel.yaml.scalarstring import LiteralScalarString


def load_yaml(content: str) -> Any:
    """Parse YAML text into Python objects."""
    parser = YAML(typ='safe')
    parser.allow_duplicate_keys = False
    return parser.load(content)


def dump_yaml(
    data: Any,
    *,
    allow_unicode: bool = True,
    default_flow_style: bool = False,
    sort_keys: bool = False,
    width: int = 120,
    literal_block_strings: bool = False,
) -> str:
    """Serialize Python objects as YAML text."""
    emitter = YAML()
    emitter.allow_unicode = allow_unicode
    emitter.default_flow_style = default_flow_style
    emitter.width = width
    emitter.sort_base_mapping_type_on_output = sort_keys

    payload = _to_literal_block_scalars(data) if literal_block_strings else data
    stream = StringIO()
    emitter.dump(payload, stream)
    return stream.getvalue()


def _to_literal_block_scalars(value: Any) -> Any:
    """Recursively convert multiline strings to literal block scalars."""
    if isinstance(value, str):
        if '\n' in value:
            return LiteralScalarString(value)
        return value
    if isinstance(value, dict):
        return {key: _to_literal_block_scalars(item) for key, item in value.items()}
    if isinstance(value, list):
        return [_to_literal_block_scalars(item) for item in value]
    return value
