"""Tests for app.services.mesh_filter"""

import os
import pytest
from app.services.mesh_filter import MeshFilter, get_mesh_filter


@pytest.fixture(scope="module")
def mf():
    """共享 MeshFilter 实例"""
    path = os.path.join(
        os.path.dirname(__file__), "..", "app", "data", "mtrees2025.bin"
    )
    return MeshFilter(path)


class TestMeshFilterLoad:
    def test_load_success(self):
        """加载 mtrees 文件，不为空"""
        path = os.path.join(
            os.path.dirname(__file__), "..", "app", "data", "mtrees2025.bin"
        )
        mf = MeshFilter(path)
        assert mf._tree_map is not None
        assert len(mf._tree_map) > 30000  # ~30k 唯一描述名

    def test_global_singleton(self):
        """get_mesh_filter 返回同一实例"""
        mf1 = get_mesh_filter()
        mf2 = get_mesh_filter()
        assert mf1 is mf2


class TestMeshByMesh:
    def test_neoplasms(self, mf):
        """Neoplasms (C04) → True"""
        assert mf.is_oncology_by_mesh([{"descriptor": "Neoplasms"}]) is True

    def test_lung_neoplasms(self, mf):
        """Lung Neoplasms (C04.588.805) → True"""
        assert mf.is_oncology_by_mesh([{"descriptor": "Lung Neoplasms"}]) is True

    def test_leukemia(self, mf):
        """Leukemia (C04.557.337) → True"""
        assert mf.is_oncology_by_mesh([{"descriptor": "Leukemia"}]) is True

    def test_melanoma(self, mf):
        """Melanoma (C04.557.665) → True"""
        assert mf.is_oncology_by_mesh([{"descriptor": "Melanoma"}]) is True

    def test_heart_diseases(self, mf):
        """Heart Diseases (C14) → False"""
        assert mf.is_oncology_by_mesh([{"descriptor": "Heart Diseases"}]) is False

    def test_empty_list(self, mf):
        """空列表 → False"""
        assert mf.is_oncology_by_mesh([]) is False

    def test_case_insensitive(self, mf):
        """大小写无关"""
        assert mf.is_oncology_by_mesh([{"descriptor": "neoplasms"}]) is True

    def test_multiple_headings_one_match(self, mf):
        """多个 MeSH 中有一个匹配 → True"""
        headings = [
            {"descriptor": "Diabetes Mellitus"},
            {"descriptor": "Breast Neoplasms"},
        ]
        assert mf.is_oncology_by_mesh(headings) is True


class TestMeshByText:
    def test_cancer_in_title(self):
        """标题含 'cancer' → True"""
        assert MeshFilter.is_oncology_by_text("lung cancer study", None) is True

    def test_cancer_in_abstract(self):
        """摘要含 'cancer' → True"""
        assert MeshFilter.is_oncology_by_text("a study", "the cancer treatment") is True

    def test_melanoma_in_title(self):
        """标题含 'melanoma' → True（修复了 keywords[:3] bug）"""
        assert MeshFilter.is_oncology_by_text("melanoma treatment", None) is True

    def test_leukaemia(self):
        """标题含 'leukaemia' → True"""
        assert MeshFilter.is_oncology_by_text("leukaemia therapy", None) is True

    def test_sarcoma(self):
        """标题含 'sarcoma' → True"""
        assert MeshFilter.is_oncology_by_text("sarcoma diagnosis", None) is True

    def test_glioma(self):
        """标题含 'glioma' → True"""
        assert MeshFilter.is_oncology_by_text("glioma research", None) is True

    def test_myeloma(self):
        """标题含 'myeloma' → True"""
        assert MeshFilter.is_oncology_by_text("myeloma treatment", None) is True

    def test_no_match(self):
        """非肿瘤文本 → False"""
        assert MeshFilter.is_oncology_by_text("heart disease", "cardiology study") is False

    def test_none_text(self):
        """None 标题和摘要 → False"""
        assert MeshFilter.is_oncology_by_text(None, None) is False

    def test_immunotherapy(self):
        """标题含 'immunotherapy' → True"""
        assert MeshFilter.is_oncology_by_text("immunotherapy advances", None) is True

    def test_oncology_term(self):
        """标题含 'oncolog' → True"""
        assert MeshFilter.is_oncology_by_text("pediatric oncology", None) is True


class TestMeshByTextScore:
    """is_oncology_by_text_score —— 精确评分模式"""

    def test_title_cancer(self):
        """标题含 'cancer' → True"""
        assert MeshFilter.is_oncology_by_text_score("lung cancer study", None) is True

    def test_title_oncology(self):
        """标题含 'oncolog' → True"""
        assert MeshFilter.is_oncology_by_text_score("pediatric oncology", None) is True

    def test_title_melanoma(self):
        """标题含 'melanoma' → True"""
        assert MeshFilter.is_oncology_by_text_score("melanoma treatment", None) is True

    def test_title_only_one_keyword(self):
        """标题命中一个词 → True"""
        assert MeshFilter.is_oncology_by_text_score("cancer study", None) is True

    def test_abstract_two_hits(self):
        """摘要含两个关键词 → True"""
        assert MeshFilter.is_oncology_by_text_score(
            None, "the cancer cells showed tumor growth"
        ) is True

    def test_abstract_single_hit(self):
        """摘要仅一个关键词 → False（评分模式）"""
        assert MeshFilter.is_oncology_by_text_score(
            None, "this study examines cancer"
        ) is False

    def test_abstract_single_weak_hit(self):
        """摘要仅 'chemotherapy' → False"""
        assert MeshFilter.is_oncology_by_text_score(
            None, "chemotherapy side effects in cardiac patients"
        ) is False

    def test_no_match(self):
        """无命中 → False"""
        assert MeshFilter.is_oncology_by_text_score(
            "heart disease", "cardiology study"
        ) is False

    def test_none_text(self):
        """None 标题和摘要 → False"""
        assert MeshFilter.is_oncology_by_text_score(None, None) is False

    def test_title_plus_abstract(self):
        """标题命中 + 摘要无关 → True（标题优先）"""
        assert MeshFilter.is_oncology_by_text_score(
            "cancer research", "statistical analysis of variance"
        ) is True

    def test_title_miss_abstract_two(self):
        """标题无命中，摘要两个词 → True"""
        assert MeshFilter.is_oncology_by_text_score(
            "heart disease", "the patient had melanoma and received chemotherapy"
        ) is True
