import time
import requests_mock

from kube_hunter.core.events import handler
from kube_hunter.core.events.types import K8sVersionDisclosure
from kube_hunter.modules.hunting.cves import K8sClusterCveHunter, ServerApiVersionEndPointAccessPE, ServerApiVersionEndPointAccessDos, CveUtils

cve_counter = 0

def test_K8sCveHunter():
    global cve_counter
    # because the hunter unregisters itself, we manually remove this option, so we can test it
    K8sClusterCveHunter.__new__ = lambda self, cls: object.__new__(self)

    e = K8sVersionDisclosure(version="1.10.1", from_endpoint="/version")
    h = K8sClusterCveHunter(e)
    h.execute()

    time.sleep(0.01)
    assert cve_counter == 2
    cve_counter = 0

    # test patched version
    e = K8sVersionDisclosure(version="v1.13.6-gke.13", from_endpoint="/version")
    h = K8sClusterCveHunter(e)
    h.execute()

    time.sleep(0.01)
    assert cve_counter == 0
    cve_counter = 0


@handler.subscribe(ServerApiVersionEndPointAccessPE)
class test_CVE_2018_1002105(object):
    def __init__(self, event):
        global cve_counter
        cve_counter += 1

@handler.subscribe(ServerApiVersionEndPointAccessDos)
class test_CVE_2019_1002100(object):
    def __init__(self, event):
        global cve_counter
        cve_counter += 1

class test_CveUtils(object):
    def test_is_downstream():
        test_cases = (
            ('1', False),
            ('1.2', False),
            ('1.2-3', True),
            ('1.2-r3', True),
            ('1.2+3', True),
            ('1.2~3', True),
            ('1.2+a3f5cb2', True),
            ('1.2-9287543', True),
            ('v1', False),
            ('v1.2', False),
            ('v1.2-3', True),
            ('v1.2-r3', True),
            ('v1.2+3', True),
            ('v1.2~3', True),
            ('v1.2+a3f5cb2', True),
            ('v1.2-9287543', True),
            ('v1.13.9-gke.3', True)
        )

        for version, expected in test_cases:
            actual = CveUtils.is_downstream_version(version)
            assert actual == expected

    def test_ignore_downstream():
        test_cases = (
            ('v2.2-abcd', ['v1.1', 'v2.3'], False),
            ('v2.2-abcd', ['v1.1', 'v2.2'], False),
            ('v1.13.9-gke.3', ['v1.14.8'], False)
        )

        for check_version, fix_versions, expected in test_cases:
            actual = CveUtils.is_vulnerable(check_version, fix_versions, True)
            assert actual == expected
