"""Super hacky module that defines "safe" representers for common string-likes.

Note that we don't need to define constructors for them, since pydantic will
handle parsing them from strings automatically.
"""

from pydantic_yaml._yaml import yaml


def _repr_as_str(dumper, node):
    return dumper.represent_str(str(node))


def _get_str_like():
    """Add representers for string-like types from stdlib and Pydantic."""

    from uuid import UUID
    from pathlib import (
        Path,
        PosixPath,
        PurePath,
        PurePosixPath,
        PureWindowsPath,
        WindowsPath,
    )

    from pydantic import types, networks

    try:
        from pydantic import SemVer
    except ImportError:
        from ._semver import SemVer

    def _chk(x) -> bool:
        try:
            return issubclass(x, (str, Path, PurePath, UUID))
        except Exception:
            return False

    candidates = (
        list(locals().values())
        + [getattr(types, v) for v in types.__all__]
        + [getattr(networks, v) for v in networks.__all__]
    )
    str_like = [v for v in candidates if _chk(v)]
    return str_like


def _add_str_representers():
    str_like = _get_str_like()
    for _typ in str_like:
        yaml.SafeDumper.add_representer(_typ, _repr_as_str)


def _py2_str(loader, node):
    """Workaround to parsing YAML files generated by Python 2"""
    return node.value


def _add_constructors():
    """Add safe constructors."""

    # Fix loading of Unicode strings from Python 2.
    yaml.SafeLoader.add_constructor("tag:yaml.org,2002:python/unicode", _py2_str)


def _inject_all():
    _add_str_representers()
    _add_constructors()
