import types
import importlib
import pytest
from pathlib import Path
import qrm.llm_cmd as llm_cmd


def test_get_dist_name_default(monkeypatch):
    # Simulate no packages_distributions and no metadata found
    monkeypatch.setattr(llm_cmd, "__package__", "qrm.llm_cmd")
    monkeypatch.setattr(llm_cmd, "metadata", lambda name: (_ for _ in ()).throw(Exception("fail")))
    result = llm_cmd._get_dist_name()
    # In this environment, the fallback is 'lr-qrm'
    assert result == "lr-qrm"


def test_get_dist_name_with_packages_distributions(monkeypatch):
    # Simulate packages_distributions returns a mapping
    monkeypatch.setattr(llm_cmd, "__package__", "qrm.llm_cmd")

    class DummyDist:
        pass

    def fake_packages_distributions():
        return {"qrm": ["lr-qrm"]}

    monkeypatch.setattr(importlib.metadata, "packages_distributions", fake_packages_distributions)
    monkeypatch.setattr(llm_cmd, "metadata", lambda name: {"Version": "1.2.3"})
    result = llm_cmd._get_dist_name()
    assert result == "lr-qrm"


def test_get_dist_name_importerror(monkeypatch):
    import builtins
    import qrm.llm_cmd as llm_cmd

    # Patch importlib.metadata.packages_distributions to raise ImportError
    import importlib.metadata

    monkeypatch.setattr(
        importlib.metadata,
        "packages_distributions",
        lambda: (_ for _ in ()).throw(ImportError("fail")),
    )
    # Patch metadata to raise Exception so fallback is used
    monkeypatch.setattr(llm_cmd, "metadata", lambda name: (_ for _ in ()).throw(Exception("fail")))
    monkeypatch.setattr(llm_cmd, "__package__", "qrm.llm_cmd")
    result = llm_cmd._get_dist_name()
    # Should return 'qrm' as fallback when all else fails
    assert result == "qrm"


def test_get_version_success(monkeypatch):
    monkeypatch.setattr(llm_cmd, "_get_dist_name", lambda: "lr-qrm")
    monkeypatch.setattr(llm_cmd, "metadata", lambda name: {"Version": "1.2.3"})
    assert llm_cmd._get_version() == "1.2.3"


def test_get_version_failure(monkeypatch):
    monkeypatch.setattr(llm_cmd, "_get_dist_name", lambda: "lr-qrm")
    monkeypatch.setattr(llm_cmd, "metadata", lambda name: (_ for _ in ()).throw(Exception("fail")))
    assert llm_cmd._get_version() == "unknown"


def test_skill_source_dir(monkeypatch):
    # Patch pkg_files to return a known path
    monkeypatch.setattr(llm_cmd, "_LLM_PACKAGE", "qrm.llm")
    monkeypatch.setattr(llm_cmd, "pkg_files", lambda pkg: Path("/tmp/fake_llm"))
    assert llm_cmd._skill_source_dir() == Path("/tmp/fake_llm")


def test_copy_skill(tmp_path, monkeypatch):
    # Setup fake source dir with a file
    src = tmp_path / "src"
    src.mkdir()
    (src / "foo.txt").write_text("bar")
    monkeypatch.setattr(llm_cmd, "_skill_source_dir", lambda: src)
    monkeypatch.setattr(llm_cmd, "_SKILL_NAME", "testskill")
    dest = tmp_path / "dest"
    dest.mkdir()
    result = llm_cmd._copy_skill(dest)
    assert (dest / "testskill" / "foo.txt").read_text() == "bar"
    assert result == dest / "testskill"
