from reports.report_types.vulnerability_report.report import VulnerabilityReport


def test_vulnerability_report_no_findings(mock_octopoes_api_connector, valid_time, ipaddressv4):
    mock_octopoes_api_connector.oois = {ipaddressv4.reference: ipaddressv4}
    mock_octopoes_api_connector.queries = {
        "IPAddress.<address[is IPPort].<ooi[is Finding]": {ipaddressv4.reference: []},
        "IPAddress.<address [is ResolvedHostname]"
        ".hostname.<netloc [is HostnameHTTPURL].<ooi [is SoftwareInstance].<ooi [is Finding]": {
            ipaddressv4.reference: []
        },
        "IPAddress.<address[is IPPort].<ooi[is Finding].finding_type": {ipaddressv4.reference: []},
        "IPAddress.<address [is ResolvedHostname]"
        ".hostname.<netloc [is HostnameHTTPURL].<ooi [is SoftwareInstance].<ooi [is Finding].finding_type": {
            ipaddressv4.reference: []
        },
        "IPAddress.<address[is ResolvedHostname].hostname": {ipaddressv4.reference: []},
    }

    report = VulnerabilityReport(mock_octopoes_api_connector)

    data = report.collect_data([str(ipaddressv4.reference)], valid_time)[str(ipaddressv4.reference)]

    assert data[str(ipaddressv4.reference)]["vulnerabilities"] == {}
    assert data[str(ipaddressv4.reference)]["summary"]["total_findings"] == 0


def test_vulnerability_report_single_finding(
    mock_octopoes_api_connector, valid_time, ipaddressv4, hostname, cve_finding_2019_8331, cve_finding_type_2019_8331
):
    mock_octopoes_api_connector.oois = {hostname.reference: hostname}
    mock_octopoes_api_connector.queries = {
        "Hostname.<hostname[is ResolvedHostname].address": {hostname.reference: [ipaddressv4]},
        "IPAddress.<address[is IPPort].<ooi[is Finding]": {ipaddressv4.reference: []},
        "IPAddress.<address[is IPPort].<ooi[is Finding].finding_type": {ipaddressv4.reference: []},
        "IPAddress.<address [is ResolvedHostname]"
        ".hostname.<netloc [is HostnameHTTPURL].<ooi [is SoftwareInstance].<ooi [is Finding]": {
            ipaddressv4.reference: [cve_finding_2019_8331]
        },
        "IPAddress.<address [is ResolvedHostname]"
        ".hostname.<netloc [is HostnameHTTPURL].<ooi [is SoftwareInstance].<ooi [is Finding].finding_type": {
            ipaddressv4.reference: [cve_finding_type_2019_8331]
        },
    }

    report = VulnerabilityReport(mock_octopoes_api_connector)

    data = report.collect_data([str(hostname.reference)], valid_time)[str(hostname.reference)]

    assert data[str(ipaddressv4.reference)]["vulnerabilities"]["CVE-2019-8331"]["cvss"]["score"] == 6.1
    assert data[str(ipaddressv4.reference)]["summary"]["total_criticals"] == 0
    assert data[str(ipaddressv4.reference)]["summary"]["total_findings"] == 1


def test_vulnerability_report_finding_no_score(
    mock_octopoes_api_connector,
    valid_time,
    ipaddressv4,
    hostname,
    cve_finding_2023_38408,
    cve_finding_type_2023_38408,
    cve_finding_no_score,
    cve_finding_type_no_score,
):
    mock_octopoes_api_connector.oois = {hostname.reference: hostname}
    mock_octopoes_api_connector.queries = {
        "Hostname.<hostname[is ResolvedHostname].address": {hostname.reference: [ipaddressv4]},
        "IPAddress.<address[is IPPort].<ooi[is Finding]": {ipaddressv4.reference: []},
        "IPAddress.<address[is IPPort].<ooi[is Finding].finding_type": {ipaddressv4.reference: []},
        "IPAddress.<address [is ResolvedHostname]"
        ".hostname.<netloc [is HostnameHTTPURL].<ooi [is SoftwareInstance].<ooi [is Finding]": {
            ipaddressv4.reference: [cve_finding_2023_38408, cve_finding_no_score]
        },
        "IPAddress.<address [is ResolvedHostname]"
        ".hostname.<netloc [is HostnameHTTPURL].<ooi [is SoftwareInstance].<ooi [is Finding].finding_type": {
            ipaddressv4.reference: [cve_finding_type_2023_38408, cve_finding_type_no_score]
        },
    }

    report = VulnerabilityReport(mock_octopoes_api_connector)

    data = report.collect_data([str(hostname.reference)], valid_time)[str(hostname.reference)]

    assert data[str(ipaddressv4.reference)]["vulnerabilities"]["CVE-2023-38408"]["cvss"]["score"] == 9.8
    assert data[str(ipaddressv4.reference)]["vulnerabilities"]["CVE-0000-0001"]["cvss"]["score"] is None
    assert data[str(ipaddressv4.reference)]["summary"]["total_criticals"] == 1
    assert data[str(ipaddressv4.reference)]["summary"]["total_findings"] == 2


def test_vulnerability_report_two_findings(
    mock_octopoes_api_connector,
    valid_time,
    ipaddressv4,
    hostname,
    cve_finding_2019_8331,
    cve_finding_type_2019_8331,
    cve_finding_2019_2019,
    cve_finding_type_2019_2019,
):
    mock_octopoes_api_connector.oois = {hostname.reference: hostname}
    mock_octopoes_api_connector.queries = {
        "Hostname.<hostname[is ResolvedHostname].address": {hostname.reference: [ipaddressv4]},
        "IPAddress.<address[is IPPort].<ooi[is Finding]": {ipaddressv4.reference: []},
        "IPAddress.<address[is IPPort].<ooi[is Finding].finding_type": {ipaddressv4.reference: []},
        "IPAddress.<address [is ResolvedHostname]"
        ".hostname.<netloc [is HostnameHTTPURL].<ooi [is SoftwareInstance].<ooi [is Finding]": {
            ipaddressv4.reference: [cve_finding_2019_8331, cve_finding_2019_2019]
        },
        "IPAddress.<address [is ResolvedHostname]"
        ".hostname.<netloc [is HostnameHTTPURL].<ooi [is SoftwareInstance].<ooi [is Finding].finding_type": {
            ipaddressv4.reference: [cve_finding_type_2019_8331, cve_finding_type_2019_2019]
        },
    }

    report = VulnerabilityReport(mock_octopoes_api_connector)

    data = report.collect_data([str(hostname.reference)], valid_time)[str(hostname.reference)]

    findings = list(data[str(ipaddressv4.reference)]["vulnerabilities"].values())
    assert findings[0]["cvss"]["score"] > findings[1]["cvss"]["score"]

    mock_octopoes_api_connector.queries = {
        "Hostname.<hostname[is ResolvedHostname].address": {hostname.reference: [ipaddressv4]},
        "IPAddress.<address[is IPPort].<ooi[is Finding]": {ipaddressv4.reference: []},
        "IPAddress.<address[is IPPort].<ooi[is Finding].finding_type": {ipaddressv4.reference: []},
        "IPAddress.<address [is ResolvedHostname]"
        ".hostname.<netloc [is HostnameHTTPURL].<ooi [is SoftwareInstance].<ooi [is Finding]": {
            ipaddressv4.reference: [cve_finding_2019_2019, cve_finding_2019_8331]
        },
        "IPAddress.<address [is ResolvedHostname]"
        ".hostname.<netloc [is HostnameHTTPURL].<ooi [is SoftwareInstance].<ooi [is Finding].finding_type": {
            ipaddressv4.reference: [cve_finding_type_2019_2019, cve_finding_type_2019_8331]
        },
    }

    report = VulnerabilityReport(mock_octopoes_api_connector)

    data = report.collect_data([str(hostname.reference)], valid_time)[str(hostname.reference)]

    findings = list(data[str(ipaddressv4.reference)]["vulnerabilities"].values())
    assert findings[0]["cvss"]["score"] > findings[1]["cvss"]["score"]
