import logging
from typing import Any, Dict, Iterable, List

import pytest

from py import config as config_module
from py.services import settings_manager as settings_manager_module


def _setup_config_environment(monkeypatch: pytest.MonkeyPatch, tmp_path) -> Dict[str, List[str]]:
    loras_dir = tmp_path / "loras"
    checkpoints_dir = tmp_path / "checkpoints"
    embeddings_dir = tmp_path / "embeddings"

    for directory in (loras_dir, checkpoints_dir, embeddings_dir):
        directory.mkdir()

    folder_paths: Dict[str, List[str]] = {
        "loras": [str(loras_dir)],
        "checkpoints": [str(checkpoints_dir)],
        "unet": [],
        "embeddings": [str(embeddings_dir)],
    }

    def fake_get_folder_paths(kind: str) -> Iterable[str]:
        return folder_paths.get(kind, [])

    monkeypatch.setattr(config_module.folder_paths, "get_folder_paths", fake_get_folder_paths)
    monkeypatch.setattr(config_module, "standalone_mode", False)
    monkeypatch.setattr(
        config_module,
        "ensure_settings_file",
        lambda logger=None: str(tmp_path / "settings.json"),
    )

    return folder_paths


def test_save_paths_renames_default_library(monkeypatch: pytest.MonkeyPatch, tmp_path):
    folder_paths = _setup_config_environment(monkeypatch, tmp_path)

    class FakeSettingsService:
        def __init__(self, default_paths: Dict[str, List[str]]):
            self._default_paths = default_paths
            self.rename_calls = []
            self.delete_calls = []
            self.upsert_calls = []
            self._renamed = False
            self.active_library = "default"

        def get_libraries(self):
            if self._renamed:
                return {"comfyui": {}}
            return {
                "default": {
                    "folder_paths": {key: list(value) for key, value in self._default_paths.items()},
                    "default_lora_root": "",
                    "default_checkpoint_root": "",
                    "default_embedding_root": "",
                }
            }

        def rename_library(self, old_name: str, new_name: str):
            self.rename_calls.append((old_name, new_name))
            self._renamed = True
            if self.active_library == old_name:
                self.active_library = new_name

        def get_active_library_name(self):
            return self.active_library

        def delete_library(self, name: str):  # pragma: no cover - defensive guard
            self.delete_calls.append(name)
            raise AssertionError("delete_library should not be invoked in this scenario")

        def upsert_library(self, name: str, **payload):
            self.upsert_calls.append((name, payload))

    fake_settings = FakeSettingsService(folder_paths)
    monkeypatch.setattr(settings_manager_module, "settings", fake_settings)

    config_instance = config_module.Config()

    assert isinstance(config_instance, config_module.Config)
    assert fake_settings.rename_calls == [("default", "comfyui")]
    assert len(fake_settings.upsert_calls) == 1

    name, payload = fake_settings.upsert_calls[0]
    assert name == "comfyui"
    
    # The Config class normalizes paths to use forward slashes for cross-platform compatibility
    # Convert expected paths to the same format for comparison
    expected_folder_paths = {
        key: [path.replace("\\", "/") for path in paths]
        for key, paths in folder_paths.items()
    }
    assert payload["folder_paths"] == expected_folder_paths
    assert payload["default_lora_root"] == folder_paths["loras"][0].replace("\\", "/")
    assert payload["default_checkpoint_root"] == folder_paths["checkpoints"][0].replace("\\", "/")
    assert payload["default_embedding_root"] == folder_paths["embeddings"][0].replace("\\", "/")
    assert payload["metadata"] == {"display_name": "ComfyUI", "source": "comfyui"}
    assert payload["activate"] is True


def test_save_paths_logs_warning_when_upsert_fails(
    monkeypatch: pytest.MonkeyPatch, tmp_path, caplog
):
    folder_paths = _setup_config_environment(monkeypatch, tmp_path)

    class RaisingSettingsService:
        def __init__(self):
            self.upsert_attempts = []
            self.active_library = "comfyui"

        def get_libraries(self):
            return {
                "comfyui": {
                    "folder_paths": {key: list(value) for key, value in folder_paths.items()},
                    "default_lora_root": "existing",
                }
            }

        def rename_library(self, *_):
            raise AssertionError("rename_library should not be invoked")

        def get_active_library_name(self):
            return self.active_library

        def upsert_library(self, name: str, **payload):
            self.upsert_attempts.append((name, payload))
            raise RuntimeError("boom")

    fake_settings = RaisingSettingsService()
    monkeypatch.setattr(settings_manager_module, "settings", fake_settings)

    with caplog.at_level(logging.WARNING, logger=config_module.logger.name):
        config_instance = config_module.Config()

    assert isinstance(config_instance, config_module.Config)
    assert fake_settings.upsert_attempts and fake_settings.upsert_attempts[0][0] == "comfyui"
    assert "Failed to save folder paths: boom" in caplog.text


def test_save_paths_repairs_empty_default_roots(monkeypatch: pytest.MonkeyPatch, tmp_path):
    folder_paths = _setup_config_environment(monkeypatch, tmp_path)

    class FakeSettingsService:
        active_library = "comfyui"
        name: str = ""
        payload: Dict[str, Any] = {}

        def get_libraries(self):
            return {
                "comfyui": {
                    "folder_paths": {key: list(value) for key, value in folder_paths.items()},
                    "default_lora_root": "",
                    "default_checkpoint_root": "",
                    "default_embedding_root": "",
                }
            }

        def rename_library(self, *_):
            raise AssertionError("rename_library should not be invoked")

        def get_active_library_name(self):
            return self.active_library

        def upsert_library(self, name: str, **payload):
            self.name = name
            self.payload = payload

    fake_settings = FakeSettingsService()
    monkeypatch.setattr(settings_manager_module, "settings", fake_settings)

    config_module.Config()

    assert fake_settings.name == "comfyui"
    assert fake_settings.payload["default_lora_root"] == folder_paths["loras"][0].replace("\\", "/")
    assert fake_settings.payload["default_checkpoint_root"] == folder_paths["checkpoints"][0].replace("\\", "/")
    assert fake_settings.payload["default_embedding_root"] == folder_paths["embeddings"][0].replace("\\", "/")


def test_save_paths_repairs_stale_default_roots(monkeypatch: pytest.MonkeyPatch, tmp_path):
    folder_paths = _setup_config_environment(monkeypatch, tmp_path)

    class FakeSettingsService:
        active_library = "comfyui"
        name: str = ""
        payload: Dict[str, Any] = {}

        def get_libraries(self):
            return {
                "comfyui": {
                    "folder_paths": {key: list(value) for key, value in folder_paths.items()},
                    "default_lora_root": "/stale/loras",
                    "default_checkpoint_root": "/stale/checkpoints",
                    "default_embedding_root": "/stale/embeddings",
                }
            }

        def rename_library(self, *_):
            raise AssertionError("rename_library should not be invoked")

        def get_active_library_name(self):
            return self.active_library

        def upsert_library(self, name: str, **payload):
            self.name = name
            self.payload = payload

    fake_settings = FakeSettingsService()
    monkeypatch.setattr(settings_manager_module, "settings", fake_settings)

    config_module.Config()

    assert fake_settings.name == "comfyui"
    assert fake_settings.payload["default_lora_root"] == folder_paths["loras"][0].replace("\\", "/")
    assert fake_settings.payload["default_checkpoint_root"] == folder_paths["checkpoints"][0].replace("\\", "/")
    assert fake_settings.payload["default_embedding_root"] == folder_paths["embeddings"][0].replace("\\", "/")


def test_save_paths_keeps_valid_default_roots(monkeypatch: pytest.MonkeyPatch, tmp_path):
    folder_paths = _setup_config_environment(monkeypatch, tmp_path)

    class FakeSettingsService:
        active_library = "comfyui"
        name: str = ""
        payload: Dict[str, Any] = {}

        def get_libraries(self):
            return {
                "comfyui": {
                    "folder_paths": {key: list(value) for key, value in folder_paths.items()},
                    "default_lora_root": folder_paths["loras"][0],
                    "default_checkpoint_root": folder_paths["checkpoints"][0],
                    "default_embedding_root": folder_paths["embeddings"][0],
                }
            }

        def rename_library(self, *_):
            raise AssertionError("rename_library should not be invoked")

        def get_active_library_name(self):
            return self.active_library

        def upsert_library(self, name: str, **payload):
            self.name = name
            self.payload = payload

    fake_settings = FakeSettingsService()
    monkeypatch.setattr(settings_manager_module, "settings", fake_settings)

    config_module.Config()

    assert fake_settings.name == "comfyui"
    assert fake_settings.payload["default_lora_root"] == folder_paths["loras"][0].replace("\\", "/")
    assert fake_settings.payload["default_checkpoint_root"] == folder_paths["checkpoints"][0].replace("\\", "/")
    assert fake_settings.payload["default_embedding_root"] == folder_paths["embeddings"][0].replace("\\", "/")


def test_save_paths_removes_template_default_library(monkeypatch, tmp_path):
    folder_paths = _setup_config_environment(monkeypatch, tmp_path)

    placeholder_paths = {
        "loras": [
            "C:/path/to/your/loras_folder",
            "C:/path/to/another/loras_folder",
        ],
        "checkpoints": [
            "C:/path/to/your/checkpoints_folder",
            "C:/path/to/another/checkpoints_folder",
        ],
        "embeddings": [
            "C:/path/to/your/embeddings_folder",
            "C:/path/to/another/embeddings_folder",
        ],
    }

    class FakeSettingsService:
        def __init__(self):
            self.libraries = {
                "default": {
                    "folder_paths": placeholder_paths,
                    "default_lora_root": "",
                    "default_checkpoint_root": "",
                    "default_embedding_root": "",
                }
            }
            self.rename_calls = []
            self.delete_calls = []
            self.upsert_calls = []
            self.active_library = "default"

        def get_libraries(self):
            return self.libraries

        def rename_library(self, old_name: str, new_name: str):
            self.rename_calls.append((old_name, new_name))
            self.libraries[new_name] = self.libraries.pop(old_name)
            if self.active_library == old_name:
                self.active_library = new_name

        def delete_library(self, name: str):
            self.delete_calls.append(name)
            self.libraries.pop(name, None)

        def upsert_library(self, name: str, **payload):
            self.upsert_calls.append((name, payload))
            self.libraries[name] = {**payload}
            if payload.get("activate"):
                self.active_library = name

        def get_active_library_name(self):
            return self.active_library

    fake_settings = FakeSettingsService()
    monkeypatch.setattr(settings_manager_module, "settings", fake_settings)

    monkeypatch.setattr(
        config_module,
        "load_settings_template",
        lambda: {"folder_paths": placeholder_paths},
    )

    config_instance = config_module.Config()

    assert isinstance(config_instance, config_module.Config)
    assert fake_settings.rename_calls == [("default", "comfyui")]
    assert not fake_settings.delete_calls
    assert len(fake_settings.upsert_calls) == 1
    assert "default" not in fake_settings.libraries
    assert set(fake_settings.libraries.keys()) == {"comfyui"}

    name, payload = fake_settings.upsert_calls[0]
    assert name == "comfyui"

    expected_folder_paths = {
        key: [path.replace("\\", "/") for path in paths]
        for key, paths in folder_paths.items()
    }
    assert payload["folder_paths"] == expected_folder_paths
    assert payload["default_lora_root"] == folder_paths["loras"][0].replace("\\", "/")
    assert (
        payload["default_checkpoint_root"]
        == folder_paths["checkpoints"][0].replace("\\", "/")
    )
    assert (
        payload["default_embedding_root"]
        == folder_paths["embeddings"][0].replace("\\", "/")
    )
    assert payload["metadata"] == {"display_name": "ComfyUI", "source": "comfyui"}
    assert payload["activate"] is True


def test_save_paths_keeps_default_roots_in_extra_paths(monkeypatch: pytest.MonkeyPatch, tmp_path):
    folder_paths = _setup_config_environment(monkeypatch, tmp_path)
    extra_lora_dir = tmp_path / "extra_loras"
    extra_checkpoint_dir = tmp_path / "extra_checkpoints"
    extra_embedding_dir = tmp_path / "extra_embeddings"

    for directory in (extra_lora_dir, extra_checkpoint_dir, extra_embedding_dir):
        directory.mkdir()

    class FakeSettingsService:
        active_library = "comfyui"
        name: str = ""
        payload: Dict[str, Any] = {}

        def get_libraries(self):
            return {
                "comfyui": {
                    "folder_paths": {key: list(value) for key, value in folder_paths.items()},
                    "extra_folder_paths": {
                        "loras": [str(extra_lora_dir)],
                        "checkpoints": [str(extra_checkpoint_dir)],
                        "embeddings": [str(extra_embedding_dir)],
                    },
                    "default_lora_root": str(extra_lora_dir),
                    "default_checkpoint_root": str(extra_checkpoint_dir),
                    "default_embedding_root": str(extra_embedding_dir),
                }
            }

        def rename_library(self, *_):
            raise AssertionError("rename_library should not be invoked")

        def get_active_library_name(self):
            return self.active_library

        def upsert_library(self, name: str, **payload):
            self.name = name
            self.payload = payload

    fake_settings = FakeSettingsService()
    monkeypatch.setattr(settings_manager_module, "settings", fake_settings)

    config_module.Config()

    assert fake_settings.name == "comfyui"
    assert fake_settings.payload["extra_folder_paths"]["loras"] == [str(extra_lora_dir).replace("\\", "/")]
    assert fake_settings.payload["extra_folder_paths"]["checkpoints"] == [
        str(extra_checkpoint_dir).replace("\\", "/")
    ]
    assert fake_settings.payload["extra_folder_paths"]["embeddings"] == [
        str(extra_embedding_dir).replace("\\", "/")
    ]
    assert fake_settings.payload["default_lora_root"] == str(extra_lora_dir).replace("\\", "/")
    assert fake_settings.payload["default_checkpoint_root"] == str(extra_checkpoint_dir).replace("\\", "/")
    assert fake_settings.payload["default_embedding_root"] == str(extra_embedding_dir).replace("\\", "/")
    assert fake_settings.payload["activate"] is True


def test_save_paths_keeps_default_roots_in_extra_paths_with_windows_slash_mismatch(
    monkeypatch: pytest.MonkeyPatch, tmp_path
):
    folder_paths = _setup_config_environment(monkeypatch, tmp_path)

    class FakeSettingsService:
        active_library = "comfyui"
        name: str = ""
        payload: Dict[str, Any] = {}

        def get_libraries(self):
            return {
                "comfyui": {
                    "folder_paths": {key: list(value) for key, value in folder_paths.items()},
                    "extra_folder_paths": {
                        "loras": ["U:\\Lora7\\Loras"],
                        "checkpoints": ["U:\\Lora7\\Models"],
                        "embeddings": [],
                    },
                    "default_lora_root": "U:/Lora7/Loras",
                    "default_checkpoint_root": "U:/Lora7/Models",
                    "default_embedding_root": folder_paths["embeddings"][0],
                }
            }

        def rename_library(self, *_):
            raise AssertionError("rename_library should not be invoked")

        def get_active_library_name(self):
            return self.active_library

        def upsert_library(self, name: str, **payload):
            self.name = name
            self.payload = payload

    fake_settings = FakeSettingsService()
    monkeypatch.setattr(settings_manager_module, "settings", fake_settings)

    config_module.Config()

    assert fake_settings.name == "comfyui"
    assert fake_settings.payload["default_lora_root"] == "U:/Lora7/Loras"
    assert fake_settings.payload["default_checkpoint_root"] == "U:/Lora7/Models"


def test_save_paths_repairs_empty_default_roots_to_extra_paths_when_primary_missing(
    monkeypatch: pytest.MonkeyPatch, tmp_path
):
    _setup_config_environment(monkeypatch, tmp_path)
    extra_lora_dir = tmp_path / "extra_loras"
    extra_lora_dir.mkdir()

    monkeypatch.setattr(
        config_module.folder_paths,
        "get_folder_paths",
        lambda kind: [] if kind == "loras" else [],
    )

    class FakeSettingsService:
        active_library = "comfyui"
        name: str = ""
        payload: Dict[str, Any] = {}

        def get_libraries(self):
            return {
                "comfyui": {
                    "folder_paths": {
                        "loras": [],
                        "checkpoints": [],
                        "unet": [],
                        "embeddings": [],
                    },
                    "extra_folder_paths": {
                        "loras": [str(extra_lora_dir)],
                    },
                    "default_lora_root": "",
                }
            }

        def rename_library(self, *_):
            raise AssertionError("rename_library should not be invoked")

        def get_active_library_name(self):
            return self.active_library

        def upsert_library(self, name: str, **payload):
            self.name = name
            self.payload = payload

    fake_settings = FakeSettingsService()
    monkeypatch.setattr(settings_manager_module, "settings", fake_settings)

    config_module.Config()

    assert fake_settings.name == "comfyui"
    assert fake_settings.payload["default_lora_root"] == str(extra_lora_dir).replace("\\", "/")


def test_save_paths_does_not_activate_comfyui_library_when_another_library_is_active(
    monkeypatch: pytest.MonkeyPatch, tmp_path
):
    folder_paths = _setup_config_environment(monkeypatch, tmp_path)

    class FakeSettingsService:
        def __init__(self):
            self.active_library = "studio"
            self.upsert_calls = []

        def get_libraries(self):
            return {
                "studio": {
                    "folder_paths": {"loras": ["/studio/loras"]},
                },
                "comfyui": {
                    "folder_paths": {key: list(value) for key, value in folder_paths.items()},
                    "default_lora_root": folder_paths["loras"][0],
                    "default_checkpoint_root": folder_paths["checkpoints"][0],
                    "default_embedding_root": folder_paths["embeddings"][0],
                },
            }

        def rename_library(self, *_):
            raise AssertionError("rename_library should not be invoked")

        def get_active_library_name(self):
            return self.active_library

        def upsert_library(self, name: str, **payload):
            self.upsert_calls.append((name, payload))

    fake_settings = FakeSettingsService()
    monkeypatch.setattr(settings_manager_module, "settings", fake_settings)

    config_module.Config()

    assert len(fake_settings.upsert_calls) == 1
    name, payload = fake_settings.upsert_calls[0]
    assert name == "comfyui"
    assert payload["activate"] is False


def test_apply_library_settings_merges_extra_paths(monkeypatch, tmp_path):
    """Test that apply_library_settings correctly merges folder_paths with extra_folder_paths."""
    loras_dir = tmp_path / "loras"
    extra_loras_dir = tmp_path / "extra_loras"
    checkpoints_dir = tmp_path / "checkpoints"
    extra_checkpoints_dir = tmp_path / "extra_checkpoints"
    embeddings_dir = tmp_path / "embeddings"
    extra_embeddings_dir = tmp_path / "extra_embeddings"

    for directory in (loras_dir, extra_loras_dir, checkpoints_dir, extra_checkpoints_dir, embeddings_dir, extra_embeddings_dir):
        directory.mkdir()

    config_instance = config_module.Config()

    folder_paths = {
        "loras": [str(loras_dir)],
        "checkpoints": [str(checkpoints_dir)],
        "unet": [],
        "embeddings": [str(embeddings_dir)],
    }
    extra_folder_paths = {
        "loras": [str(extra_loras_dir)],
        "checkpoints": [str(extra_checkpoints_dir)],
        "unet": [],
        "embeddings": [str(extra_embeddings_dir)],
    }

    library_config = {
        "folder_paths": folder_paths,
        "extra_folder_paths": extra_folder_paths,
    }

    config_instance.apply_library_settings(library_config)

    assert str(loras_dir) in config_instance.loras_roots
    assert str(extra_loras_dir) in config_instance.extra_loras_roots
    assert str(checkpoints_dir) in config_instance.base_models_roots
    assert str(extra_checkpoints_dir) in config_instance.extra_checkpoints_roots
    assert str(embeddings_dir) in (config_instance.embeddings_roots or [])
    assert str(extra_embeddings_dir) in config_instance.extra_embeddings_roots


def test_apply_library_settings_without_extra_paths(monkeypatch, tmp_path):
    """Test that apply_library_settings works when extra_folder_paths is not provided."""
    loras_dir = tmp_path / "loras"
    checkpoints_dir = tmp_path / "checkpoints"
    embeddings_dir = tmp_path / "embeddings"

    for directory in (loras_dir, checkpoints_dir, embeddings_dir):
        directory.mkdir()

    config_instance = config_module.Config()

    folder_paths = {
        "loras": [str(loras_dir)],
        "checkpoints": [str(checkpoints_dir)],
        "unet": [],
        "embeddings": [str(embeddings_dir)],
    }

    library_config = {
        "folder_paths": folder_paths,
    }

    config_instance.apply_library_settings(library_config)

    assert str(loras_dir) in config_instance.loras_roots
    assert config_instance.extra_loras_roots == []
    assert str(checkpoints_dir) in config_instance.base_models_roots
    assert config_instance.extra_checkpoints_roots == []
    assert str(embeddings_dir) in (config_instance.embeddings_roots or [])
    assert config_instance.extra_embeddings_roots == []


def test_extra_paths_deduplication(monkeypatch, tmp_path):
    """Test that extra paths are stored separately from main paths in Config."""
    loras_dir = tmp_path / "loras"
    extra_loras_dir = tmp_path / "extra_loras"
    loras_dir.mkdir()
    extra_loras_dir.mkdir()

    config_instance = config_module.Config()

    folder_paths = {
        "loras": [str(loras_dir)],
        "checkpoints": [],
        "unet": [],
        "embeddings": [],
    }
    extra_folder_paths = {
        "loras": [str(extra_loras_dir)],
        "checkpoints": [],
        "unet": [],
        "embeddings": [],
    }

    library_config = {
        "folder_paths": folder_paths,
        "extra_folder_paths": extra_folder_paths,
    }

    config_instance.apply_library_settings(library_config)

    assert config_instance.loras_roots == [str(loras_dir)]
    assert config_instance.extra_loras_roots == [str(extra_loras_dir)]


def test_apply_library_settings_ignores_extra_lora_path_overlapping_primary_symlink(
    monkeypatch, tmp_path, caplog
):
    """Extra LoRA paths should be ignored when they resolve to the same target as a primary root."""
    real_loras_dir = tmp_path / "loras_real"
    real_loras_dir.mkdir()
    loras_link = tmp_path / "loras_link"
    loras_link.symlink_to(real_loras_dir, target_is_directory=True)

    config_instance = config_module.Config()

    library_config = {
        "folder_paths": {
            "loras": [str(loras_link)],
            "checkpoints": [],
            "unet": [],
            "embeddings": [],
        },
        "extra_folder_paths": {
            "loras": [str(real_loras_dir)],
            "checkpoints": [],
            "unet": [],
            "embeddings": [],
        },
    }

    with caplog.at_level("WARNING", logger=config_module.logger.name):
        config_instance.apply_library_settings(library_config)

    assert config_instance.loras_roots == [str(loras_link)]
    assert config_instance.extra_loras_roots == []

    warning_messages = [
        record.message
        for record in caplog.records
        if record.levelname == "WARNING"
        and "same lora folder" in record.message.lower()
    ]
    assert len(warning_messages) == 1
    assert "comfyui model paths" in warning_messages[0].lower()
    assert "extra folder paths" in warning_messages[0].lower()
    assert "duplicate items" in warning_messages[0].lower()


def test_apply_library_settings_detects_overlap_case_insensitively(
    monkeypatch, tmp_path, caplog
):
    """Overlap detection should use case-insensitive comparison on Windows-like paths."""
    real_loras_dir = tmp_path / "loras_real"
    real_loras_dir.mkdir()
    loras_link = tmp_path / "loras_link"
    loras_link.symlink_to(real_loras_dir, target_is_directory=True)

    original_exists = config_module.os.path.exists
    original_realpath = config_module.os.path.realpath
    original_normcase = config_module.os.path.normcase

    def fake_exists(path):
        if isinstance(path, str) and path.lower() in {
            str(loras_link).lower(),
            str(real_loras_dir).lower(),
            str(loras_link).upper().lower(),
            str(real_loras_dir).upper().lower(),
        }:
            return True
        return original_exists(path)

    def fake_realpath(path, *args, **kwargs):
        if isinstance(path, str):
            lowered = path.lower()
            if lowered == str(loras_link).lower():
                return str(real_loras_dir)
            if lowered == str(real_loras_dir).lower():
                return str(real_loras_dir)
        return original_realpath(path, *args, **kwargs)

    monkeypatch.setattr(config_module.os.path, "exists", fake_exists)
    monkeypatch.setattr(config_module.os.path, "realpath", fake_realpath)
    monkeypatch.setattr(
        config_module.os.path,
        "normcase",
        lambda value: original_normcase(value).lower(),
    )

    config_instance = config_module.Config()
    primary_path = str(loras_link).replace("loras_link", "LORAS_LINK")
    extra_path = str(real_loras_dir).replace("loras_real", "loras_real")

    library_config = {
        "folder_paths": {
            "loras": [primary_path],
            "checkpoints": [],
            "unet": [],
            "embeddings": [],
        },
        "extra_folder_paths": {
            "loras": [extra_path.upper()],
            "checkpoints": [],
            "unet": [],
            "embeddings": [],
        },
    }

    with caplog.at_level("WARNING", logger=config_module.logger.name):
        config_instance.apply_library_settings(library_config)

    assert config_instance.loras_roots == [primary_path]
    assert config_instance.extra_loras_roots == []
    assert any("same lora folder" in record.message.lower() for record in caplog.records)


def test_apply_library_settings_ignores_missing_extra_lora_paths(monkeypatch, tmp_path, caplog):
    """Missing extra paths should be ignored without overlap warnings."""
    loras_dir = tmp_path / "loras"
    loras_dir.mkdir()
    missing_extra = tmp_path / "missing_loras"

    config_instance = config_module.Config()
    library_config = {
        "folder_paths": {
            "loras": [str(loras_dir)],
            "checkpoints": [],
            "unet": [],
            "embeddings": [],
        },
        "extra_folder_paths": {
            "loras": [str(missing_extra)],
            "checkpoints": [],
            "unet": [],
            "embeddings": [],
        },
    }

    with caplog.at_level("WARNING", logger=config_module.logger.name):
        config_instance.apply_library_settings(library_config)

    assert config_instance.loras_roots == [str(loras_dir)]
    assert config_instance.extra_loras_roots == []
    assert not any("same lora folder" in record.message.lower() for record in caplog.records)


def test_apply_library_settings_ignores_extra_lora_path_overlapping_primary_root_symlink(
    tmp_path, caplog
):
    """Extra LoRA paths should be ignored when already reachable via a first-level symlink under the primary root."""
    loras_dir = tmp_path / "loras"
    loras_dir.mkdir()
    external_dir = tmp_path / "external_loras"
    external_dir.mkdir()
    link_dir = loras_dir / "link"
    link_dir.symlink_to(external_dir, target_is_directory=True)

    config_instance = config_module.Config()
    library_config = {
        "folder_paths": {
            "loras": [str(loras_dir)],
            "checkpoints": [],
            "unet": [],
            "embeddings": [],
        },
        "extra_folder_paths": {
            "loras": [str(external_dir)],
            "checkpoints": [],
            "unet": [],
            "embeddings": [],
        },
    }

    with caplog.at_level("WARNING", logger=config_module.logger.name):
        config_instance.apply_library_settings(library_config)

    assert config_instance.loras_roots == [str(loras_dir)]
    assert config_instance.extra_loras_roots == []
    assert any(
        "same lora folder" in record.message.lower()
        for record in caplog.records
    )


def test_save_paths_removes_stale_empty_default_when_comfyui_exists(
    monkeypatch: pytest.MonkeyPatch, tmp_path,
):
    """When an empty-shell 'default' library coexists with 'comfyui', the
    stale 'default' entry should be removed and 'comfyui' activated."""
    folder_paths = _setup_config_environment(monkeypatch, tmp_path)

    class FakeSettingsService:
        def __init__(self):
            # Replicate the user's settings.json: empty default + populated comfyui
            self.libraries = {
                "default": {
                    "folder_paths": {},
                    "extra_folder_paths": {},
                    "default_lora_root": "",
                    "default_checkpoint_root": "",
                    "default_unet_root": "",
                    "default_embedding_root": "",
                    "recipes_path": "",
                },
                "comfyui": {
                    "folder_paths": {
                        key: list(value) for key, value in folder_paths.items()
                    },
                    "default_lora_root": folder_paths["loras"][0],
                    "default_checkpoint_root": folder_paths["checkpoints"][0],
                    "default_embedding_root": folder_paths["embeddings"][0],
                },
            }
            # No active_library key — get_active_library_name() falls back to
            # dict order, returning "default".
            self.active_library = "default"
            self.delete_calls: list[str] = []
            self.upsert_calls: list[tuple[str, dict[str, Any]]] = []

        def get_libraries(self):
            return dict(self.libraries)

        def delete_library(self, name: str):
            self.delete_calls.append(name)
            self.libraries.pop(name, None)

        def rename_library(self, *_):
            raise AssertionError("rename_library should not be invoked")

        def get_active_library_name(self):
            return self.active_library

        def upsert_library(self, name: str, **payload):
            self.upsert_calls.append((name, payload))
            self.libraries[name] = {**payload}
            if payload.get("activate"):
                self.active_library = name

    fake_settings = FakeSettingsService()
    monkeypatch.setattr(settings_manager_module, "settings", fake_settings)

    config_module.Config()

    assert fake_settings.delete_calls == ["default"]
    assert "default" not in fake_settings.libraries
    assert set(fake_settings.libraries.keys()) == {"comfyui"}

    assert len(fake_settings.upsert_calls) == 1
    name, payload = fake_settings.upsert_calls[0]
    assert name == "comfyui"
    assert payload["activate"] is True
    assert fake_settings.active_library == "comfyui"
