import pytest

from pydantic_core import ValidationError

from aegis_ai.agents import rh_feature_agent
from aegis_ai.features import component, cve
from tests.utils.llm_cache import get_cached_response, cache_response

pytestmark = pytest.mark.asyncio


async def test_suggest_impact_with_test_model():
    test_name = "test_suggest_impact_with_test_model"

    # Try to get cached response first
    result = get_cached_response(test_name)

    if not result:
        # Make real LLM call and cache the response
        llm_result = await cve.SuggestImpact(rh_feature_agent).exec("CVE-2025-0725")
        result = llm_result.output.model_dump_json(indent=4)
        cache_response(test_name, result)

    suggestimpact = cve.SuggestImpactModel.model_validate_json(result)
    assert isinstance(suggestimpact, cve.SuggestImpactModel)
    assert suggestimpact.impact == "LOW"
    assert (
        suggestimpact.disclaimer
        == "This response was generated by Aegis AI (https://github.com/RedHatProductSecurity/aegis-ai) using generative AI for informational purposes. All findings should be validated by a human expert."
    )


async def test_suggest_cwe_with_test_model(set_test_allowed_cwe_ids_env_var):
    test_name = "test_suggest_cwe_with_test_model"

    result = get_cached_response(test_name)

    if not result:
        llm_result = await cve.SuggestCWE(rh_feature_agent).exec("CVE-2025-0725")
        result = llm_result.output.model_dump_json(indent=4)
        cache_response(test_name, result)

    suggestcwe = cve.SuggestCWEModel.model_validate_json(result)
    assert isinstance(suggestcwe, cve.SuggestCWEModel)
    assert suggestcwe.cwe == ["CWE-190"]


async def test_identify_pii_with_test_model():
    test_name = "test_identify_pii_with_test_model"
    cve_id = "CVE-2025-0725"

    result = get_cached_response(test_name)

    if not result:
        llm_result = await cve.IdentifyPII(rh_feature_agent).exec(cve_id)
        result = llm_result.output.model_dump_json(indent=4)
        cache_response(test_name, result)

    piireport = cve.PIIReportModel.model_validate_json(result)
    assert isinstance(piireport, cve.PIIReportModel)
    assert not piireport.contains_PII  # is false


async def test_suggest_description_with_test_model():
    test_name = "test_suggest_description_with_test_model"

    result = get_cached_response(test_name)

    if not result:
        llm_result = await cve.SuggestDescriptionText(rh_feature_agent).exec(
            "CVE-2025-0725"
        )
        result = llm_result.output.model_dump_json(indent=4)
        cache_response(test_name, result)

    suggestdescription = cve.SuggestDescriptionModel.model_validate_json(result)
    assert isinstance(suggestdescription, cve.SuggestDescriptionModel)
    assert (
        suggestdescription.suggested_title
        == "libcurl: gzip decompression buffer overflow"
    )


async def test_suggest_statement_with_test_model():
    test_name = "test_suggest_statement_with_test_model"

    result = get_cached_response(test_name)

    if not result:
        llm_result = await cve.SuggestStatementText(rh_feature_agent).exec(
            "CVE-2025-0725"
        )
        result = llm_result.output.model_dump_json(indent=4)
        cache_response(test_name, result)

    suggeststatement = cve.SuggestStatementModel.model_validate_json(result)
    assert isinstance(suggeststatement, cve.SuggestStatementModel)
    assert (
        suggeststatement.suggested_statement
        == "This issue has a low impact on Red Hat products as it only affects libcurl when used with zlib versions 1.2.0.3 or older, which are not widely present in affected Red Hat components. The vulnerability requires specific conditions for exploitation related to automatic gzip decompression."
    )


async def test_cvss_diff_explain_with_test_model():
    test_name = "test_cvss_diff_explain_with_test_model"

    result = get_cached_response(test_name)

    if not result:
        llm_result = await cve.CVSSDiffExplainer(rh_feature_agent).exec("CVE-2025-0725")
        result = llm_result.output.model_dump_json(indent=4)
        cache_response(test_name, result)

    cvssdiffexplain = cve.CVSSDiffExplainerModel.model_validate_json(result)
    assert isinstance(cvssdiffexplain, cve.CVSSDiffExplainerModel)
    assert (
        cvssdiffexplain.redhat_cvss3_vector
        == "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"
    )


async def test_component_intelligence_test_model():
    test_name = "test_component_intelligence_test_model"

    result = get_cached_response(test_name)

    if not result:
        llm_result = await component.ComponentIntelligence(rh_feature_agent).exec(
            "curl"
        )
        result = llm_result.output.model_dump_json(indent=4)
        cache_response(test_name, result)

    componentintelligence = component.ComponentIntelligenceModel.model_validate_json(
        result
    )
    assert isinstance(componentintelligence, component.ComponentIntelligenceModel)
    assert componentintelligence.popularity_score == 1
    assert componentintelligence.confidence == 0.95


async def test_suggest_impact_with_bad_cve_test_model():
    with pytest.raises(ValidationError) as excinfo:
        await cve.SuggestImpact(rh_feature_agent).exec("BAD-CVE-ID")

    assert "String should match pattern" in str(excinfo)
