import yaml

from typing import (
    Dict,
    List,
    Union,
)


def get_yaml_config(
    config_path: str,
    version: str,
) -> Dict[str, Union[Dict, int, str]]:
    """ Get the configuration from the YAML file.

    Args:
        config_path (str): The path to the YAML file.
        version (str): The version.

    Returns:
        Dict[str, Union[Dict, int, str]]: The configuration.
    """

    with open(
            file=config_path,
            mode='r',
            encoding='utf-8',
    ) as yaml_file:
        config_str = yaml_file.read()

        yaml_file.close()

    config = yaml.safe_load(stream=config_str)

    # Cannot use the logger due to the logger has NOT been initialized yet.
    assert config['lfs_path'] and config['model_path'], \
            'The LFS path and model path must be set.'

    update_dict = {
        '${LFS_PATH}': config['lfs_path'],
        '${MODEL_PATH}': config['model_path'],
        '${TARGET_TAG}': config['target_tag'],
        '${TARGET_VERSION}': config['target_version'],
        '${VERSION}': version,
    }

    config = update_yaml_config(
        update_dict=update_dict,
        item=config,
    )

    return config


def update_yaml_config(
    update_dict: Dict[str, str],
    item: Union[bool, Dict, float, int, List, str],
) -> Union[bool, Dict, float, int, List, str]:
    """ Update the configuration.

    Args:
        update_dict (Dict[str, str]): The update dictionary.
        item (Union[bool, Dict, float, int, List, str]): The item.

    Returns:
        Union[bool, Dict, float, int, List, str]: The updated item.
    """

    if isinstance(
            item,
            Dict,
    ):
        for key, value in item.items():
            item[key] = update_yaml_config(
                update_dict=update_dict,
                item=value,
            )
    elif isinstance(
            item,
            List,
    ):
        for index in range(len(item)):
            item[index] = update_yaml_config(
                update_dict=update_dict,
                item=item[index],
            )
    elif isinstance(
            item,
            str,
    ):
        for key, value in update_dict.items():
            if value is not None:
                item = item.replace(
                    key,
                    value,
                )

    return item
