# tests/test_core.py
"""
Unit and integration tests for Dendro Core models, strict categorization, and DAG tree structures.
Runs headlessly in CI environments using offscreen Qt platform.
"""

import sys
import pytest
from PyQt6.QtWidgets import QApplication
from PyQt6.QtCore import Qt

from core.backend import PackageInfo, DependencyNode, PackageState
from core.models import DependencyTreeModel, PackageFilterProxyModel


@pytest.fixture(scope="session")
def qapp():
    app = QApplication.instance()
    if app is None:
        app = QApplication(sys.argv)
    yield app


@pytest.fixture
def sample_packages():
    return [
        PackageInfo(
            name="firefox",
            version="154.0",
            release="1.fc44",
            arch="x86_64",
            summary="Mozilla Firefox Web Browser",
            group="Applications/Internet",
            size_bytes=82000000,
            state=PackageState.INSTALLED,
            is_orphan=False,
            is_desktop_app=True,
            is_cli_tool=False,
            is_fedora_core=False,
            is_c_lib=False,
            is_firmware=False,
            is_font=False,
            is_locale=False,
            is_devel=False,
            is_theme=False,
            is_library=False
        ),
        PackageInfo(
            name="htop",
            version="3.3.0",
            release="1.fc44",
            arch="x86_64",
            summary="Interactive process viewer for terminal",
            group="Applications/System",
            size_bytes=350000,
            state=PackageState.INSTALLED,
            is_orphan=False,
            is_desktop_app=False,
            is_cli_tool=True,
            is_fedora_core=False,
            is_c_lib=False,
            is_firmware=False,
            is_font=False,
            is_locale=False,
            is_devel=False,
            is_theme=False,
            is_library=False
        ),
        PackageInfo(
            name="kernel",
            version="7.1.8",
            release="1.fc44",
            arch="x86_64",
            summary="The Linux Kernel",
            group="System Environment/Kernel",
            size_bytes=150000000,
            state=PackageState.INSTALLED,
            is_orphan=False,
            is_desktop_app=False,
            is_cli_tool=False,
            is_fedora_core=True,
            is_c_lib=False,
            is_firmware=False,
            is_font=False,
            is_locale=False,
            is_devel=False,
            is_theme=False,
            is_library=False
        ),
        PackageInfo(
            name="libpng",
            version="1.6.58",
            release="1.fc44",
            arch="x86_64",
            summary="A library of functions for manipulating PNG image format files",
            group="System Environment/Libraries",
            size_bytes=420000,
            state=PackageState.INSTALLED,
            is_orphan=True,
            is_desktop_app=False,
            is_cli_tool=False,
            is_fedora_core=False,
            is_c_lib=True,
            is_firmware=False,
            is_font=False,
            is_locale=False,
            is_devel=False,
            is_theme=False,
            is_library=True
        )
    ]


def test_tree_model_population(qapp, sample_packages):
    model = DependencyTreeModel()
    model.set_packages(sample_packages)

    assert model.rowCount() == 4
    assert model.columnCount() == DependencyTreeModel.COL_COUNT

    idx_name = model.index(0, DependencyTreeModel.COL_NAME)
    assert idx_name.data(Qt.ItemDataRole.DisplayRole) == "firefox"


def test_strict_desktop_and_cli_categorization(qapp, sample_packages):
    """تست تفکیک قطعی و ایزوله Desktop Apps از ابزارهای CLI و کتابخانه‌ها"""
    model = DependencyTreeModel()
    model.set_packages(sample_packages)

    proxy = PackageFilterProxyModel()
    proxy.setSourceModel(model)

    # ۱. برنامه‌های دسکتاپ فقط باید firefox باشد (htop نباید اینجا باشد)
    proxy.set_category_filter("user_apps")
    assert proxy.rowCount() == 1
    assert proxy.index(0, 0).data(Qt.ItemDataRole.DisplayRole) == "firefox"

    # ۲. ابزارهای خط فرمان فقط باید htop باشد
    proxy.set_category_filter("cli_tools")
    assert proxy.rowCount() == 1
    assert proxy.index(0, 0).data(Qt.ItemDataRole.DisplayRole) == "htop"

    # ۳. ستون‌های اصلی فدورا فقط باید kernel باشد
    proxy.set_category_filter("fedora_core")
    assert proxy.rowCount() == 1
    assert proxy.index(0, 0).data(Qt.ItemDataRole.DisplayRole) == "kernel"

    # ۴. کتابخانه‌های C/C++ و بسته‌های بی‌استفاده (Orphans) فقط باید libpng باشد
    proxy.set_category_filter("c_libs")
    assert proxy.rowCount() == 1
    assert proxy.index(0, 0).data(Qt.ItemDataRole.DisplayRole) == "libpng"


def test_on_demand_lazy_dependency_attachment(qapp, sample_packages):
    """تست الصاق درجا و آنی وابستگی‌ها به نود درخت"""
    model = DependencyTreeModel()
    model.set_packages(sample_packages)

    deps = [
        DependencyNode(
            raw_requirement="libpng16.so.16()(64bit)",
            resolved_package_name="libpng",
            version_constraint=">= 1.6.0",
            is_satisfied=True,
            is_cycle=False
        )
    ]

    # الصاق وابستگی به فایرفاکس
    model.attach_dependencies("firefox", deps)

    parent_idx = model.index(0, DependencyTreeModel.COL_NAME)
    assert model.rowCount(parent_idx) == 1

    child_idx = model.index(0, DependencyTreeModel.COL_NAME, parent_idx)
    assert child_idx.data(Qt.ItemDataRole.DisplayRole) == "libpng"


def test_queue_state_toggling(qapp, sample_packages):
    model = DependencyTreeModel()
    model.set_packages(sample_packages)

    idx_firefox = model.index(0, 0)
    model.toggle_queue_state(idx_firefox)

    installs, removals = model.get_queued_packages()
    assert "firefox" in removals
