#!/usr/bin/python3
"""Tests for slpkg/audit.py using pytest."""

import json
from unittest.mock import MagicMock, patch

import pytest
from slpkg.audit import Audit


@pytest.fixture
def mock_config():
    """Mock config_load for Audit."""
    with patch("slpkg.audit.config_load") as mock:
        mock.cyan = ""
        mock.green = ""
        mock.red = ""
        mock.yellow = ""
        mock.endc = ""
        mock.bold = ""
        yield mock


@pytest.fixture
def audit_inst(mock_config):
    """Fixture for Audit instance with mocked dependencies."""
    with patch("slpkg.audit.Utilities", autospec=True), \
         patch("slpkg.audit.ViewProcess", autospec=True):
        inst = Audit({"option_quiet": False}, packages=[])
        return inst


def test_query_osv_batch_success(audit_inst):
    """Test successful OSV batch query parsing."""
    pkg_list = [("pkg1", "1.0"), ("pkg2", "2.0")]
    mock_response = MagicMock()
    mock_response.status = 200
    mock_response.data = json.dumps({
        "results": [
            {"vulns": [{"id": "CVE-1", "summary": "vuln1"}]},
            {"vulns": []}
        ]
    }).encode("utf-8")
    
    with patch.object(audit_inst.http, "request", return_value=mock_response):
        found = audit_inst._query_osv_batch(pkg_list)
        assert "pkg1" in found
        assert found["pkg1"][0]["id"] == "CVE-1"
        assert "pkg2" not in found


def test_get_packages_to_audit(audit_inst):
    """Test package filtering logic."""
    all_installed = {"pkg1": "pkg1-1.0", "pkg2": "pkg2-2.0"}
    
    # 1. No filter (all packages)
    audit_inst.packages = []
    assert audit_inst._get_packages_to_audit(all_installed) == all_installed
    
    # 2. Filter by name
    audit_inst.packages = ["pkg1"]
    audit_inst.utils.apply_package_pattern.return_value = ["pkg1"]
    matched = audit_inst._get_packages_to_audit(all_installed)
    assert matched == {"pkg1": "pkg1-1.0"}


def test_display_results_with_details_fallback(audit_inst, capsys):
    """Test result display using details if summary is missing."""
    found_vulns = {
        "pkg1": [
            {"id": "CVE-SUM", "summary": "Small summary"},
            {"id": "CVE-DET", "details": "Long details that should be truncated... " * 10}
        ]
    }
    
    audit_inst._display_results(found_vulns, 1)
    captured = capsys.readouterr()
    
    assert "Small summary" in captured.out
    assert "Long details" in captured.out
    assert ".." in captured.out # Truncation marker
    assert "CVE-SUM" in captured.out
    assert "CVE-DET" in captured.out


def test_run_audit_no_vulns(audit_inst, capsys):
    """Test run() when no vulnerabilities are found."""
    audit_inst.utils.all_installed.return_value = {"pkg1": "pkg1-1.0"}
    audit_inst.utils.split_package.return_value = {"version": "1.0"}
    audit_inst._query_osv_batch = MagicMock(return_value={})
    
    audit_inst.run()
    captured = capsys.readouterr()
    assert "No known vulnerabilities found" in captured.out
