import pytest
from pathlib import Path
import toml
from comfy_resolve.config import (
    get_config_path,
    config_exists,
    load_config,
    write_default_config,
    infer_model_paths,
    get_model_path,
)
from typing import Any

# Mock home directory for testing
@pytest.fixture
def mock_config_home(tmp_path: Path):
    original_home = Path.home
    Path.home = lambda: tmp_path
    yield tmp_path
    Path.home = original_home

@pytest.fixture
def setup_config_file(mock_config_home: Path):
    config_dir = mock_config_home / ".config" / "comfy-resolve"
    config_dir.mkdir(parents=True, exist_ok=True)
    config_path = config_dir / "config.toml"
    
    content = """
comfyui_dir = "/mock/comfyui"

[paths]
checkpoints = "/override/checkpoints"
loras = "/mock/comfyui/models/loras_override"

[api_keys]
huggingface = "hf_token_123"
civitai = "civitai_token_456"
"""
    with open(config_path, "w") as f:
        f.write(content)
    return config_path

def test_get_config_path(mock_config_home: Path):
    expected_path = mock_config_home / ".config" / "comfy-resolve" / "config.toml"
    assert get_config_path() == expected_path

def test_config_exists_false(mock_config_home: Path):
    assert not config_exists()

def test_config_exists_true(setup_config_file: Path):
    assert config_exists()

def test_load_config(setup_config_file: Path):
    config = load_config()
    assert config["comfyui_dir"] == "/mock/comfyui"
    assert config["paths"]["checkpoints"] == "/override/checkpoints"
    assert config["api_keys"]["huggingface"] == "hf_token_123"

def test_infer_model_paths():
    comfyui_dir = "/test/comfyui"
    inferred = infer_model_paths(comfyui_dir)
    assert inferred["checkpoints"] == Path("/test/comfyui/models/checkpoints")
    assert inferred["loras"] == Path("/test/comfyui/models/loras")
    assert inferred["vae"] == Path("/test/comfyui/models/vae")
    assert inferred["text_encoders"] == Path("/test/comfyui/models/text_encoders")
    assert inferred["controlnet"] == Path("/test/comfyui/models/controlnet")
    assert inferred["upscale_models"] == Path("/test/comfyui/models/upscale_models")
    assert inferred["embeddings"] == Path("/test/comfyui/models/embeddings")
    assert inferred["clip"] == Path("/test/comfyui/models/clip")
    assert inferred["ipadapter"] == Path("/test/comfyui/models/ipadapter")
    assert inferred["gligen"] == Path("/test/comfyui/models/gligen")
    assert inferred["style_models"] == Path("/test/comfyui/models/style_models")
    assert inferred["hypernetworks"] == Path("/test/comfyui/models/hypernetworks")
    assert inferred["diffusers"] == Path("/test/comfyui/models/diffusers")
    assert inferred["unclip"] == Path("/test/comfyui/models/unclip")
    assert inferred["insightface"] == Path("/test/comfyui/models/insightface")
    assert inferred["photomaker"] == Path("/test/comfyui/models/photomaker")
    assert inferred["sadtalker"] == Path("/test/comfyui/models/sadtalker")
    assert inferred["audio"] == Path("/test/comfyui/models/audio")
    assert inferred["other"] == Path("/test/comfyui/models/other")


def test_write_default_config(mock_config_home: Path):
    comfyui_dir = "/test/comfyui_install"
    config_path = write_default_config(comfyui_dir)
    
    assert config_path.is_file()
    config_content = config_path.read_text()
    
    assert f'comfyui_dir = "{Path(comfyui_dir).as_posix()}"' in config_content
    assert '# checkpoints = "/test/comfyui_install/models/checkpoints"' in config_content
    assert "[api_keys]" in config_content
    assert "huggingface = \"\"" in config_content
    assert "civitai = \"\"" in config_content
    assert "[download]" in config_content
    assert "concurrent = 2" in config_content
    assert "max_retries = 3" in config_content
    assert "[resolution]" in config_content
    assert 'preferred_source = "huggingface"' in config_content
    assert 'auto_confidence_threshold = "high"' in config_content
    assert "[mappings]" in config_content

def test_get_model_path_with_override(setup_config_file: Path):
    config = load_config()
    path = get_model_path("checkpoints", config)
    assert path == Path("/override/checkpoints")

def test_get_model_path_with_inferred(setup_config_file: Path):
    config = load_config()
    path = get_model_path("vae", config)
    assert path == Path("/mock/comfyui/models/vae")

def test_get_model_path_unknown_asset_type(setup_config_file: Path):
    config = load_config()
    path = get_model_path("unknown_asset", config)
    assert path == Path("/mock/comfyui/models/other")

def test_get_model_path_no_comfyui_dir_in_config(mock_config_home: Path):
    config_dir = mock_config_home / ".config" / "comfy-resolve"
    config_dir.mkdir(parents=True, exist_ok=True)
    config_path = config_dir / "config.toml"
    with open(config_path, "w") as f:
        f.write("""[paths]
checkpoints = "/override/checkpoints" """)
    
    config = load_config()
    with pytest.raises(ValueError, match="comfyui_dir not found in config."):
        get_model_path("checkpoints", config)
