import yaml
from yaml.parser import ParserError
from yaml import load, Loader
from yaml.scanner import ScannerError
from api.testium import print_debug
from runtime.tum_except import ETUMSyntaxError
import io

# Use the libyaml-backed loader (much faster parsing) when PyYAML was built
# with it, falling back to the pure-Python loader otherwise. The C loader
# raises the same ParserError/ScannerError and supports the same custom
# constructors (!include) and construct_* helpers the TUM loaders rely on.
YAML_BASE_LOADER = yaml.CLoader if getattr(yaml, "__with_libyaml__", False) else yaml.Loader


def print_yaml(file: io.TextIOWrapper, file_name):
    """ Prints YAML file if debug mode is activated.
    """
    file.seek(0)
    print_debug(f"Dump of \"{file_name}\":")
    lines = file.read().splitlines()
    lines = [f"{i+1:>3d}: " + lines[i] for i in range(len(lines))]
    print_debug("\n".join(lines))


def yaml_load(file, real_file_name: str, loader: Loader):
    try:
        return load(file, loader)

    except ParserError as e:
        if isinstance(file, (io.TextIOWrapper, io.StringIO)):
            print_yaml(file, real_file_name)
        raise ETUMSyntaxError(f"yaml file parsing error: " + str(e), real_file_name)
    except ScannerError as e:
        if isinstance(file, (io.TextIOWrapper, io.StringIO)):
            print_yaml(file, real_file_name)
        raise ETUMSyntaxError("yaml file scanning error: " + str(e), real_file_name)
