# (C) Datadog, Inc. 2019-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
import pytest
from mock import MagicMock
from requests import HTTPError

from datadog_checks.base import AgentCheck
from datadog_checks.dev.http import MockResponse

from .common import HARBOR_COMPONENTS, HARBOR_VERSION, VERSION_1_5, VERSION_1_6, VERSION_1_8


@pytest.mark.usefixtures("patch_requests")
def test_check_health(aggregator, harbor_check, harbor_api):
    base_tags = ['tag1:val1', 'tag2']
    harbor_check._check_health(harbor_api, base_tags)

    if harbor_api.harbor_version >= VERSION_1_8:
        components = HARBOR_COMPONENTS
        for c in components:
            aggregator.assert_service_check('harbor.status', AgentCheck.OK, tags=base_tags + ['component:{}'.format(c)])
    elif harbor_api.harbor_version >= VERSION_1_6:
        aggregator.assert_service_check('harbor.status', AgentCheck.OK, tags=base_tags + ['component:chartmuseum'])
        aggregator.assert_service_check('harbor.status', AgentCheck.OK, tags=base_tags)
    elif harbor_api.harbor_version >= VERSION_1_5:
        aggregator.assert_service_check('harbor.status', AgentCheck.OK, tags=base_tags)
    else:
        aggregator.assert_service_check('harbor.status', AgentCheck.UNKNOWN, tags=base_tags)


@pytest.mark.usefixtures("patch_requests")
def test_check_registries_health(aggregator, harbor_check, harbor_api):
    tags = ['tag1:val1', 'tag2']
    harbor_check._check_registries_health(harbor_api, tags)
    tags.append('registry:demo')
    aggregator.assert_service_check('harbor.registry.status', AgentCheck.OK, tags=tags)


@pytest.mark.usefixtures("patch_requests")
def test_submit_project_metrics(aggregator, harbor_check, harbor_api):
    tags = ['tag1:val1', 'tag2']
    harbor_check._submit_project_metrics(harbor_api, tags)
    aggregator.assert_metric('harbor.projects.count', 2, tags=tags)


@pytest.mark.usefixtures("patch_requests")
def test_submit_disk_metrics(aggregator, harbor_check, harbor_api):
    tags = ['tag1:val1', 'tag2']
    harbor_check._submit_disk_metrics(harbor_api, tags)
    aggregator.assert_metric('harbor.disk.free', 5e5, tags=tags)
    aggregator.assert_metric('harbor.disk.total', 1e6, tags=tags)


@pytest.mark.usefixtures("patch_requests")
@pytest.mark.skipif(HARBOR_VERSION < VERSION_1_5, reason="The registry.read_only metric is submitted for Harbor 1.5+")
def test_submit_read_only_status(aggregator, harbor_check, harbor_api):
    tags = ['tag1:val1', 'tag2']
    harbor_check._submit_read_only_status(harbor_api, tags)
    aggregator.assert_metric('harbor.registry.read_only', 0, tags=tags)


def test_api__make_get_request(harbor_api):
    harbor_api.http = MagicMock()
    harbor_api.http.get = MagicMock(return_value=MockResponse(json_data={'json': True}))
    assert harbor_api._make_get_request('{base_url}/api/path') == {"json": True}

    harbor_api.http.get = MagicMock(return_value=MockResponse(status_code=500))
    with pytest.raises(HTTPError):
        harbor_api._make_get_request('{base_url}/api/path')


def test_api__make_paginated_get_request(harbor_api):
    expected_result = [{'item': i} for i in range(20)]
    paginated_result = [[expected_result[i], expected_result[i + 1]] for i in range(0, len(expected_result) - 1, 2)]
    values = []
    for r in paginated_result:
        values.append(MockResponse(json_data=r, headers={'link': 'Link: <unused_url>; rel=next; type="text/plain"'}))
    values[-1].headers.pop('link')

    harbor_api.http = MagicMock()
    harbor_api.http.get = MagicMock(side_effect=values)

    assert harbor_api._make_paginated_get_request('{base_url}/api/path') == expected_result


def test_api__make_post_request(harbor_api):
    harbor_api.http = MagicMock()
    harbor_api.http.post = MagicMock(return_value=MockResponse(json_data={'json': True}))
    assert harbor_api._make_post_request('{base_url}/api/path') == {"json": True}

    harbor_api.http.post = MagicMock(return_value=MockResponse(status_code=500))
    with pytest.raises(HTTPError):
        harbor_api._make_post_request('{base_url}/api/path')

[((377, 418), 'pytest.mark.usefixtures', 'pytest.mark.usefixtures', (['"""patch_requests"""'], {}), "('patch_requests')\n", (400, 418), False, 'import pytest\n'), ((1311, 1352), 'pytest.mark.usefixtures', 'pytest.mark.usefixtures', (['"""patch_requests"""'], {}), "('patch_requests')\n", (1334, 1352), False, 'import pytest\n'), ((1642, 1683), 'pytest.mark.usefixtures', 'pytest.mark.usefixtures', (['"""patch_requests"""'], {}), "('patch_requests')\n", (1665, 1683), False, 'import pytest\n'), ((1918, 1959), 'pytest.mark.usefixtures', 'pytest.mark.usefixtures', (['"""patch_requests"""'], {}), "('patch_requests')\n", (1941, 1959), False, 'import pytest\n'), ((2251, 2292), 'pytest.mark.usefixtures', 'pytest.mark.usefixtures', (['"""patch_requests"""'], {}), "('patch_requests')\n", (2274, 2292), False, 'import pytest\n'), ((2294, 2416), 'pytest.mark.skipif', 'pytest.mark.skipif', (['(HARBOR_VERSION < VERSION_1_5)'], {'reason': '"""The registry.read_only metric is submitted for Harbor 1.5+"""'}), "(HARBOR_VERSION < VERSION_1_5, reason=\n    'The registry.read_only metric is submitted for Harbor 1.5+')\n", (2312, 2416), False, 'import pytest\n'), ((2717, 2728), 'mock.MagicMock', 'MagicMock', ([], {}), '()\n', (2726, 2728), False, 'from mock import MagicMock\n'), ((3526, 3537), 'mock.MagicMock', 'MagicMock', ([], {}), '()\n', (3535, 3537), False, 'from mock import MagicMock\n'), ((3564, 3593), 'mock.MagicMock', 'MagicMock', ([], {'side_effect': 'values'}), '(side_effect=values)\n', (3573, 3593), False, 'from mock import MagicMock\n'), ((3756, 3767), 'mock.MagicMock', 'MagicMock', ([], {}), '()\n', (3765, 3767), False, 'from mock import MagicMock\n'), ((2989, 3013), 'pytest.raises', 'pytest.raises', (['HTTPError'], {}), '(HTTPError)\n', (3002, 3013), False, 'import pytest\n'), ((4031, 4055), 'pytest.raises', 'pytest.raises', (['HTTPError'], {}), '(HTTPError)\n', (4044, 4055), False, 'import pytest\n'), ((2778, 2816), 'datadog_checks.dev.http.MockResponse', 'MockResponse', ([], {'json_data': "{'json': True}"}), "(json_data={'json': True})\n", (2790, 2816), False, 'from datadog_checks.dev.http import MockResponse\n'), ((2949, 2978), 'datadog_checks.dev.http.MockResponse', 'MockResponse', ([], {'status_code': '(500)'}), '(status_code=500)\n', (2961, 2978), False, 'from datadog_checks.dev.http import MockResponse\n'), ((3372, 3470), 'datadog_checks.dev.http.MockResponse', 'MockResponse', ([], {'json_data': 'r', 'headers': '{\'link\': \'Link: <unused_url>; rel=next; type="text/plain"\'}'}), '(json_data=r, headers={\'link\':\n    \'Link: <unused_url>; rel=next; type="text/plain"\'})\n', (3384, 3470), False, 'from datadog_checks.dev.http import MockResponse\n'), ((3818, 3856), 'datadog_checks.dev.http.MockResponse', 'MockResponse', ([], {'json_data': "{'json': True}"}), "(json_data={'json': True})\n", (3830, 3856), False, 'from datadog_checks.dev.http import MockResponse\n'), ((3991, 4020), 'datadog_checks.dev.http.MockResponse', 'MockResponse', ([], {'status_code': '(500)'}), '(status_code=500)\n', (4003, 4020), False, 'from datadog_checks.dev.http import MockResponse\n')]