import pytest
import mock
from jenkinsapi.jenkins import JenkinsBase


@pytest.fixture(scope='function')
def jenkinsbase():
    return JenkinsBase('http://localhost:8080/', poll=False)


def test_called_in__poll(jenkinsbase, monkeypatch, mocker):
    def fake_poll(cls, tree=None):   # pylint: disable=unused-argument
        return {
            'description': "My jobs",
            'jobs': [{
                'name': "Foo",
                'url': "http://localhost:8080/job/Foo",
                'color': "blue",
            }],
            'name': "All",
            'property': [],
            'url': "http://localhost:8080/view/All/",
        }

    monkeypatch.setattr(JenkinsBase, '_poll', fake_poll)
    stub = mocker.stub()
    monkeypatch.setattr(JenkinsBase, 'resolve_job_folders', stub)

    jenkinsbase.poll()

    stub.assert_called_once_with(
        [
            {
                'name': "Foo",
                'url': "http://localhost:8080/job/Foo",
                'color': "blue",
            },
        ],
    )


def test_no_folders(jenkinsbase):
    jobs = [
        {
            'name': "Foo",
            'url': "http://localhost:8080/job/Foo",
            'color': "blue",
        },
        {
            'name': "Bar",
            'url': "http://localhost:8080/job/Bar",
            'color': "disabled",
        },
    ]

    assert jenkinsbase.resolve_job_folders(jobs) == [
        {
            'name': "Foo",
            'url': "http://localhost:8080/job/Foo",
            'color': "blue",
        },
        {
            'name': "Bar",
            'url': "http://localhost:8080/job/Bar",
            'color': "disabled",
        },
    ]


def test_empty_folder(jenkinsbase, monkeypatch, mocker):
    def fake_get_data(cls, url, tree=None):  # pylint: disable=unused-argument
        return {'jobs': []}

    monkeypatch.setattr(JenkinsBase, 'get_data', fake_get_data)
    spy = mocker.spy(jenkinsbase, 'get_data')

    jobs = [
        {
            'name': "Folder1",
            'url': "http://localhost:8080/job/Folder1",
        },
    ]

    assert jenkinsbase.resolve_job_folders(jobs) == []
    spy.assert_called_once_with(
        'http://localhost:8080/job/Folder1/api/python',
        tree='jobs[name,color]'
    )


def test_folder_job_mix(jenkinsbase, monkeypatch, mocker):
    def fake_get_data(cls, url, tree=None):  # pylint: disable=unused-argument
        return {
            'jobs': [
                {
                    'name': "Bar",
                    'url': "http://localhost:8080/job/Folder1/job/Bar",
                    'color': "disabled",
                }
            ]
        }

    monkeypatch.setattr(JenkinsBase, 'get_data', fake_get_data)
    spy = mocker.spy(jenkinsbase, 'get_data')

    jobs = [
        {
            'name': "Foo",
            'url': "http://localhost:8080/job/Foo",
            'color': "blue",
        },
        {
            'name': "Folder1",
            'url': "http://localhost:8080/job/Folder1",
        },
    ]

    assert jenkinsbase.resolve_job_folders(jobs) == [
        {
            'name': "Foo",
            'url': "http://localhost:8080/job/Foo",
            'color': "blue",
        },
        {
            'name': "Bar",
            'url': "http://localhost:8080/job/Folder1/job/Bar",
            'color': "disabled",
        }
    ]

    spy.assert_called_once_with(
        'http://localhost:8080/job/Folder1/api/python',
        tree='jobs[name,color]'
    )


def test_multiple_folders(jenkinsbase, monkeypatch, mocker):
    def fake_get_data(cls, url, tree=None):  # pylint: disable=unused-argument
        # first call
        if 'Folder1' in url:
            return {'jobs': [
                {
                    'name': "Foo",
                    'url': "http://localhost:8080/job/Folder1/job/Foo",
                    'color': "disabled",
                },
            ]}

        if 'Folder2' in url:
            # second call
            return {'jobs': [
                {
                    'name': "Bar",
                    'url': "http://localhost:8080/job/Folder2/job/Bar",
                    'color': "blue",
                },
            ]}

    monkeypatch.setattr(JenkinsBase, 'get_data', fake_get_data)
    spy = mocker.spy(jenkinsbase, 'get_data')

    jobs = [
        {
            'name': "Folder1",
            'url': "http://localhost:8080/job/Folder1",
        },
        {
            'name': "Folder2",
            'url': "http://localhost:8080/job/Folder2",
        },
    ]

    assert jenkinsbase.resolve_job_folders(jobs) == [
        {
            'name': "Foo",
            'url': "http://localhost:8080/job/Folder1/job/Foo",
            'color': "disabled",
        },
        {
            'name': "Bar",
            'url': "http://localhost:8080/job/Folder2/job/Bar",
            'color': "blue",
        },
    ]

    assert spy.call_args_list == [
        mock.call(
            'http://localhost:8080/job/Folder1/api/python',
            tree='jobs[name,color]'
        ),
        mock.call(
            'http://localhost:8080/job/Folder2/api/python',
            tree='jobs[name,color]'
        ),
    ]


def test_multiple_folder_levels(jenkinsbase, monkeypatch, mocker):
    def fake_get_data(cls, url, tree=None):  # pylint: disable=unused-argument
        if 'Folder1' in url and 'Folder2' not in url:
            # first call
            return {'jobs': [
                {
                    'name': "Bar",
                    'url': "http://localhost:8080/job/Folder1/job/Bar",
                    'color': "disabled",
                },
                {
                    'name': "Folder2",
                    'url': "http://localhost:8080/job/Folder1/job/Folder2",
                }
            ]}

        if 'Folder2' in url:
            # second call
            return {
                'jobs': [
                    {
                        'name': "Baz",
                        'url': (
                            "http://localhost:8080/job/Folder1/"
                            "job/Folder2/job/Baz"
                        ),
                        'color': "disabled",
                    },
                ]
            }

    monkeypatch.setattr(JenkinsBase, 'get_data', fake_get_data)
    spy = mocker.spy(jenkinsbase, 'get_data')

    jobs = [
        {
            'name': "Foo",
            'url': "http://localhost:8080/job/Foo",
            'color': "blue",
        },
        {
            'name': "Folder1",
            'url': "http://localhost:8080/job/Folder1",
        },
    ]

    assert jenkinsbase.resolve_job_folders(jobs) == [
        {
            'name': "Foo",
            'url': "http://localhost:8080/job/Foo",
            'color': "blue",
        },
        {
            'name': "Bar",
            'url': "http://localhost:8080/job/Folder1/job/Bar",
            'color': "disabled",
        },
        {
            'name': "Baz",
            'url': ("http://localhost:8080/job/Folder1"
                    "/job/Folder2/job/Baz"),
            'color': "disabled",
        },
    ]

    assert spy.call_args_list == [
        mock.call(
            'http://localhost:8080/job/Folder1/api/python',
            tree='jobs[name,color]'
        ),
        mock.call(
            'http://localhost:8080/job/Folder1'
            '/job/Folder2/api/python',
            tree='jobs[name,color]'
        ),
    ]
