# Copyright (C) 2021  Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import json
import os
from unittest import mock

import pytest

import tests.utils
from passerelle.contrib.esirius_swi.models import ESiriusSwi
from passerelle.contrib.esirius_swi.utils import compute_status

pytestmark = pytest.mark.django_db

TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'esirius_swi')


def get_xml_file(filename):
    with open(os.path.join(TEST_BASE_DIR, filename), 'rb') as desc:
        return desc.read()


def get_json_file(filename):
    with open(os.path.join(TEST_BASE_DIR, "%s.json" % filename)) as fd:
        return json.load(fd)


@pytest.fixture
def v1_service_wsdl():
    return get_xml_file('v1.0.wsdl')


@pytest.fixture
def connector(db):
    return tests.utils.setup_access_rights(
        ESiriusSwi.objects.create(
            slug='test', base_url='https://example.org/eSirius/webservices/sitewaitingindicator/'
        )
    )


@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
def test_soap_content_error(mocked_post, mocked_get, v1_service_wsdl, connector, app):
    mocked_get.return_value = mock.Mock(content=v1_service_wsdl)
    mocked_post.return_value = mock.Mock(
        content='oups',
        status_code=200,
        headers={'Content-Type': 'text/xml'},
    )
    resp = app.get('/esirius-swi/test/get_all_indicators')
    assert resp.json['err'] == 1
    assert resp.json['err_desc'] == "'NoneType' object has no attribute 'getroottree'"


@pytest.mark.parametrize(
    'resource, time, closed, minutes',
    [
        (0, '00:01:39', True, None),
        (1, '-', False, None),
        (2, '00:01:39', False, 2),
        (99, '01:59:00', False, 120),
    ],
)
def test_status(resource, time, closed, minutes):
    data = {
        'resourceNumber': resource,
        'estimatedAvgWaitingTime': time,
    }
    compute_status(data)
    assert data == {
        'resourceNumber': resource,
        'estimatedAvgWaitingTime': time,
        'closed': closed,
        'estimatedAvgWaitingTimeInMinutes': minutes,
    }


@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
def test_get_all_indicator(mocked_post, mocked_get, v1_service_wsdl, connector, app):
    mocked_get.return_value = mock.Mock(content=v1_service_wsdl)
    mocked_post.return_value = mock.Mock(
        content=get_xml_file('get_all_indicators.xml'),
        status_code=200,
        headers={'Content-Type': 'text/xml'},
    )
    resp = app.get('/esirius-swi/test/get_all_indicators')
    assert resp.json['err'] == 0
    assert resp.json['data'] == [
        {
            'cumulatedWaitingVisitorNumber': 6,
            'estimatedAvgWaitingTime': '00:03:29',
            'estimatedMaxWaitingTime': '-',
            'estimatedWaitingTimeForNextTicket': '-',
            'name': "Braine-l'Alleud",
            'realAvgWaitingTime': '00:03:51',
            'realMaxWaitingTime': '00:06:42',
            'resourceNumber': 9.000003,
            'serviceWaitingIndicatorWSList': None,
            'siteCode': 'site1',
            'waitingVisitorNumber': None,
            'weekHoursWS': None,
            'closed': False,
            'estimatedAvgWaitingTimeInMinutes': 4,
        }
    ]
