import pytest
from collections import namedtuple
import pathlib
import os
import rna.path
import rna.config

pytest.importorskip("hydra")
pytest.importorskip("omegaconf")


Request = namedtuple("Request", "platform")


@pytest.fixture(scope="session", params=(Request("posix"), Request("nt")))
def cfg(request):
    platform = request.param.platform
    dialect = "yaml"
    base_dir = rna.path.resolve(os.path.dirname(__file__), "resources")
    merge_configs = [
        rna.path.resolve(base_dir, f"local.{dialect}"),
        rna.path.resolve(base_dir, f"user.{dialect}"),
    ]
    if platform == "nt":
        # Mock windows os.uname Attribute error
        uname = os.uname
        del os.uname
    elif platform == "posix" and os.name == "nt":
        # Mock existing os.uname under nt
        import platform as platform_module
        from collections import namedtuple

        def uname():
            Uname = namedtuple("Uname", "system node release version machine")
            return Uname(*platform_module.uname())

        os.uname = uname
    cfg = rna.config.api(rna, *merge_configs, config_dir=base_dir)
    yield cfg
    if platform == "nt":
        os.uname = uname
    elif platform == "posix" and os.name == "nt":
        del os.uname


def test_package_variables(cfg):
    assert cfg.title == "My Config"
    assert cfg.package.name == "rna"
    assert cfg.package.path == rna.path.resolve(os.path.dirname(__file__), "..", "rna")
    assert cfg.package.developer == cfg.package.co_author


def test_merged_configs(cfg):
    assert cfg.database.port == 5432
    assert cfg.database.password == "passw123"
    assert pathlib.Path(cfg.general.data).name == "resources"
    resources = rna.path.resolve(os.path.dirname(__file__), "resources")
    assert pathlib.Path(cfg.general.data).samefile(resources)
    assert cfg.database.path == cfg.general.data + "/db.sqlite"
    assert cfg.database.cache_path.endswith("local")


def test_os_variables(cfg):
    assert cfg.package.cache == rna.path.resolve("~/tmp")


def test_fallback(cfg):
    assert rna.config.fallback(cfg.database, "backup", "port") == 5432
    assert rna.config.fallback(cfg.database, "backup", "path") == rna.path.resolve(
        cfg.general.data, "../bup/db_bup.sqlite"
    )


def test_inception(cfg):
    assert "os.home" not in cfg.database.cache_path  # resolved os.home
