# Copyright (C) 2019  The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU Affero General Public License version 3, or any later version
# See top-level LICENSE file for more information

import re

from datetime import datetime, timedelta, timezone
from functools import partial

import pytest
import requests

from swh.core.pytest_plugin import get_response_cb

from swh.web.common.models import SaveOriginRequest
from swh.web.common.origin_save import get_save_origin_task_info
from swh.web.config import get_config


_es_url = 'http://esnode1.internal.softwareheritage.org:9200'
_es_workers_index_url = '%s/swh_workers-*' % _es_url


@pytest.fixture(autouse=True)
def requests_mock_datadir(datadir, requests_mock_datadir):
    """Override default behavior to deal with post method

    """
    cb = partial(get_response_cb, datadir=datadir)
    requests_mock_datadir.post(re.compile('https?://'), body=cb)
    return requests_mock_datadir


@pytest.mark.django_db
def test_get_save_origin_archived_task_info(mocker):
    _get_save_origin_task_info_test(mocker, task_archived=True)


@pytest.mark.django_db
def test_get_save_origin_task_info_with_es(mocker):
    _get_save_origin_task_info_test(mocker, es_available=True)


@pytest.mark.django_db
def test_get_save_origin_task_info_without_es(mocker):
    _get_save_origin_task_info_test(mocker, es_available=False)


def _get_save_origin_task_info_test(mocker, task_archived=False,
                                    es_available=True):
    swh_web_config = get_config()

    if es_available:
        swh_web_config.update({'es_workers_index_url': _es_workers_index_url})
    else:
        swh_web_config.update({'es_workers_index_url': ''})

    sor_id = 4473

    SaveOriginRequest.objects.create(
        id=sor_id,
        request_date=datetime(2019, 8, 30, 23, 7, 3, 474294,
                              tzinfo=timezone.utc),
        visit_type='git',
        origin_url='https://gitlab.com/inkscape/inkscape',
        status='accepted',
        loading_task_id=203525448,
        visit_date=datetime(2019, 8, 30, 23, 18, 11, 54341,
                            tzinfo=timezone.utc)
    )

    mock_scheduler = mocker.patch('swh.web.common.origin_save.scheduler')
    task = {
        'arguments': {
            'args': [],
            'kwargs': {
                'repo_url': 'https://gitlab.com/inkscape/inkscape'
            }
        },
        'current_interval': timedelta(days=64),
        'id': 203525448,
        'next_run': datetime(2019, 8, 30, 23, 7, 1, 614823),
        'policy': 'oneshot',
        'priority': 'high',
        'retries_left': 0,
        'status': 'disabled',
        'type': 'load-git'
    } if not task_archived else None
    mock_scheduler.get_tasks.return_value = [task]

    task_run = {
        'backend_id': 'f00c712c-e820-41ce-a07c-9bf8df914205',
        'ended': datetime(2019, 8, 30, 23, 18, 13, 770800),
        'id': 654270631,
        'metadata': {},
        'scheduled': datetime(2019, 8, 30, 23, 8, 34, 282021),
        'started': None,
        'status': 'failed',
        'task': 203525448
    }
    mock_scheduler.get_task_runs.return_value = [task_run]

    es_response = requests.post('%s/_search' % _es_workers_index_url).json()

    task_exec_data = es_response['hits']['hits'][-1]['_source']

    sor_task_info = get_save_origin_task_info(sor_id)

    expected_result = {
        'type': task['type'],
        'arguments': task['arguments'],
        'id': task['id'],
        'backend_id': task_run['backend_id'],
        'scheduled': task_run['scheduled'],
        'ended': task_run['ended'],
        'status': task_run['status'],
    } if not task_archived else {}

    if es_available and not task_archived:
        expected_result.update({
            'message': task_exec_data['message'],
            'name': task_exec_data['swh_task_name'],
            'worker': task_exec_data['hostname']
        })

    assert sor_task_info == expected_result
