import pytest
import mock
from jenkinsapi.jenkins import Jenkins
from jenkinsapi.executors import Executors
from jenkinsapi.executor import Executor


DATAM = {
    "assignedLabels": [{}],
    "description": None,
    "jobs": [],
    "mode": "NORMAL",
    "nodeDescription": "the master Jenkins node",
    "nodeName": "",
    "numExecutors": 2,
    "overallLoad": {},
    "primaryView": {"name": "All", "url": "http://localhost:8080/"},
    "quietingDown": False,
    "slaveAgentPort": 0,
    "unlabeledLoad": {},
    "useCrumbs": False,
    "useSecurity": False,
    "views": [
        {"name": "All", "url": "http://localhost:8080/"},
        {"name": "BigMoney", "url": "http://localhost:8080/view/BigMoney/"},
    ],
}

DATA0 = {
    "actions": [],
    "displayName": "host0.host.com",
    "executors": [{}, {}, {}, {}, {}, {}, {}, {}],
    "icon": "computer.png",
    "idle": False,
    "jnlpAgent": True,
    "launchSupported": False,
    "loadStatistics": {},
    "manualLaunchAllowed": True,
    "monitorData": {
        "hudson.node_monitors.SwapSpaceMonitor": {
            "availablePhysicalMemory": 8462417920,
            "availableSwapSpace": 0,
            "totalPhysicalMemory": 75858042880,
            "totalSwapSpace": 0,
        },
        "hudson.node_monitors.ArchitectureMonitor": "Linux (amd64)",
        "hudson.node_monitors.ResponseTimeMonitor": {"average": 2},
        "hudson.node_monitors.TemporarySpaceMonitor": {
            "path": "/tmp",
            "size": 430744551424,
        },
        "hudson.node_monitors.DiskSpaceMonitor": {
            "path": "/data/jenkins",
            "size": 1214028627968,
        },
        "hudson.node_monitors.ClockMonitor": {"diff": 1},
    },
    "numExecutors": 8,
    "offline": False,
    "offlineCause": None,
    "offlineCauseReason": "",
    "oneOffExecutors": [{}, {}],
    "temporarilyOffline": False,
}

DATA1 = {
    "actions": [],
    "displayName": "host1.host.com",
    "executors": [{}, {}],
    "icon": "computer.png",
    "idle": False,
    "jnlpAgent": True,
    "launchSupported": False,
    "loadStatistics": {},
    "manualLaunchAllowed": True,
    "monitorData": {
        "hudson.node_monitors.SwapSpaceMonitor": {
            "availablePhysicalMemory": 8462417920,
            "availableSwapSpace": 0,
            "totalPhysicalMemory": 75858042880,
            "totalSwapSpace": 0,
        },
        "hudson.node_monitors.ArchitectureMonitor": "Linux (amd64)",
        "hudson.node_monitors.ResponseTimeMonitor": {"average": 2},
        "hudson.node_monitors.TemporarySpaceMonitor": {
            "path": "/tmp",
            "size": 430744551424,
        },
        "hudson.node_monitors.DiskSpaceMonitor": {
            "path": "/data/jenkins",
            "size": 1214028627968,
        },
        "hudson.node_monitors.ClockMonitor": {"diff": 1},
    },
    "numExecutors": 2,
    "offline": False,
    "offlineCause": None,
    "offlineCauseReason": "",
    "oneOffExecutors": [{}, {}],
    "temporarilyOffline": False,
}

DATA2 = {
    "actions": [],
    "displayName": "host2.host.com",
    "executors": [{}, {}, {}, {}],
    "icon": "computer.png",
    "idle": False,
    "jnlpAgent": True,
    "launchSupported": False,
    "loadStatistics": {},
    "manualLaunchAllowed": True,
    "monitorData": {
        "hudson.node_monitors.SwapSpaceMonitor": {
            "availablePhysicalMemory": 8462417920,
            "availableSwapSpace": 0,
            "totalPhysicalMemory": 75858042880,
            "totalSwapSpace": 0,
        },
        "hudson.node_monitors.ArchitectureMonitor": "Linux (amd64)",
        "hudson.node_monitors.ResponseTimeMonitor": {"average": 2},
        "hudson.node_monitors.TemporarySpaceMonitor": {
            "path": "/tmp",
            "size": 430744551424,
        },
        "hudson.node_monitors.DiskSpaceMonitor": {
            "path": "/data/jenkins",
            "size": 1214028627968,
        },
        "hudson.node_monitors.ClockMonitor": {"diff": 1},
    },
    "numExecutors": 4,
    "offline": False,
    "offlineCause": None,
    "offlineCauseReason": "",
    "oneOffExecutors": [{}, {}],
    "temporarilyOffline": False,
}

DATA3 = {
    "actions": [],
    "displayName": "host3.host.com",
    "executors": [{}],
    "icon": "computer.png",
    "idle": False,
    "jnlpAgent": True,
    "launchSupported": False,
    "loadStatistics": {},
    "manualLaunchAllowed": True,
    "monitorData": {
        "hudson.node_monitors.SwapSpaceMonitor": {
            "availablePhysicalMemory": 8462417920,
            "availableSwapSpace": 0,
            "totalPhysicalMemory": 75858042880,
            "totalSwapSpace": 0,
        },
        "hudson.node_monitors.ArchitectureMonitor": "Linux (amd64)",
        "hudson.node_monitors.ResponseTimeMonitor": {"average": 2},
        "hudson.node_monitors.TemporarySpaceMonitor": {
            "path": "/tmp",
            "size": 430744551424,
        },
        "hudson.node_monitors.DiskSpaceMonitor": {
            "path": "/data/jenkins",
            "size": 1214028627968,
        },
        "hudson.node_monitors.ClockMonitor": {"diff": 1},
    },
    "numExecutors": 1,
    "offline": False,
    "offlineCause": None,
    "offlineCauseReason": "",
    "oneOffExecutors": [{}, {}],
    "temporarilyOffline": False,
}

EXEC0 = {
    "currentExecutable": {
        "number": 4168,
        "url": "http://localhost:8080/job/testjob/4168/",
    },
    "currentWorkUnit": {},
    "idle": False,
    "likelyStuck": False,
    "number": 0,
    "progress": 48,
}

EXEC1 = {
    "currentExecutable": None,
    "currentWorkUnit": None,
    "idle": True,
    "likelyStuck": False,
    "number": 0,
    "progress": -1,
}


@pytest.fixture(scope="function")
def jenkins(monkeypatch):
    def fake_poll(cls, tree=None):  # pylint: disable=unused-argument
        return DATAM

    monkeypatch.setattr(Jenkins, "_poll", fake_poll)
    return Jenkins("http://localhost:8080")


def test_repr(jenkins):
    # Can we produce a repr string for this object
    assert repr(jenkins)


def test_check_url(jenkins):
    assert jenkins.baseurl == "http://localhost:8080"


def test_get_executors(jenkins, monkeypatch):
    def fake_poll_extr(cls, tree=None):  # pylint: disable=unused-argument
        return EXEC0

    def fake_poll_extrs(cls, tree=None):  # pylint: disable=unused-argument
        return DATA3

    monkeypatch.setattr(Executor, "_poll", fake_poll_extr)
    monkeypatch.setattr(Executors, "_poll", fake_poll_extrs)

    exec_info = jenkins.get_executors(DATA3["displayName"])

    assert isinstance(exec_info, object)
    assert isinstance(repr(exec_info), str)

    for ex in exec_info:
        assert ex.get_progress() == 48, "Should return 48 %"


def testis_idle(jenkins, monkeypatch):
    def fake_poll_extr(cls, tree=None):  # pylint: disable=unused-argument
        return EXEC1

    def fake_poll_extrs(cls, tree=None):  # pylint: disable=unused-argument
        return DATA3

    monkeypatch.setattr(Executor, "_poll", fake_poll_extr)
    monkeypatch.setattr(Executors, "_poll", fake_poll_extrs)

    exec_info = jenkins.get_executors("host3.host.com")

    assert isinstance(exec_info, object)
    for ex in exec_info:
        assert ex.get_progress() == -1, "Should return 48 %"
        assert ex.is_idle() is True, "Should return True"
        assert repr(ex) == "<jenkinsapi.executor.Executor host3.host.com 0>"


@mock.patch.object(Executor, "_poll")
def test_likely_stuck(jenkins, monkeypatch):
    def fake_poll_extr(cls, tree=None):  # pylint: disable=unused-argument
        return EXEC0

    monkeypatch.setattr(Executor, "_poll", fake_poll_extr)

    baseurl = "http://localhost:8080/computer/host0.host.com/executors/0"
    nodename = "host0.host.com"
    single_executer = Executor(baseurl, nodename, jenkins, "0")
    assert single_executer.likely_stuck() is False


def test_get_current_executable(jenkins, monkeypatch):
    def fake_poll_extr(cls, tree=None):  # pylint: disable=unused-argument
        return EXEC0

    monkeypatch.setattr(Executor, "_poll", fake_poll_extr)

    baseurl = "http://localhost:8080/computer/host0.host.com/executors/0"
    nodename = "host0.host.com"
    single_executer = Executor(baseurl, nodename, jenkins, "0")
    assert single_executer.get_current_executable()["number"] == 4168
    assert (
        single_executer.get_current_executable()["url"]
        == "http://localhost:8080/job/testjob/4168/"
    )
