import datetime
import os

import pytest
import responses
from django.core.management import call_command
from git import Repo

from scrutiny.projects.models import (
    InstalledService,
    InstalledVersion,
    Module,
    Platform,
    Project,
    Service,
    Version,
)
from tests.utils import login

pytestmark = pytest.mark.django_db


CHRONO_ISSUE_1 = {
    'issue': {
        'id': 1,
        'project': {'id': 6, 'name': 'chrono'},
        'author': {'id': 42, 'name': 'Jon Doe'},
        'assigned_to': {'id': 42, 'name': 'Jon Doe'},
        'subject': 'Fix bug',
    }
}


CHRONO_ISSUE_2 = {
    'issue': {
        'id': 2,
        'project': {'id': 6, 'name': 'chrono'},
        'author': {'id': 42, 'name': 'Jon Doe'},
        'assigned_to': {'id': 43, 'name': 'Jane Doe'},
        'subject': 'Improve code',
    }
}


def test_home(app):
    resp = app.get('/')
    assert 'Welcome' in resp.text


@responses.activate
def test_project_issues(app, settings, admin_user):
    project = Project.objects.create(title='SaaS2', slug='saas2')
    service = Service.objects.create(project=project, title='Chrono', slug='chrono')
    module = Module.objects.create(name='chrono', repository_url='https://git.example.org/chrono.git')

    test_platform = Platform.objects.create(project=project, title='Test', slug='test', order=1)
    prod_platform = Platform.objects.create(project=project, title='Prod', slug='prod', order=2)

    installed_service_test = InstalledService.objects.create(
        service=service, platform=test_platform, url='https://chrono.example.org/'
    )
    installed_service_prod = InstalledService.objects.create(
        service=service, platform=prod_platform, url='https://chrono.example.org/'
    )

    # previous release
    previous_release_date = (datetime.datetime.today() - datetime.timedelta(days=30)).replace(
        hour=10, minute=10
    )
    upcoming_release_date = previous_release_date + datetime.timedelta(days=9)

    test_version = Version.objects.create(module=module, version='0.1')
    test_installed_version = InstalledVersion.objects.create(
        service=installed_service_test, version=test_version, timestamp=previous_release_date
    )
    # upcoming release
    test_version = Version.objects.create(module=module, version='1.1')
    test_installed_version = InstalledVersion.objects.create(
        service=installed_service_test, version=test_version, timestamp=upcoming_release_date
    )

    # previous release
    prod_version = Version.objects.create(module=module, version='0.1')
    prod_installed_version = InstalledVersion.objects.create(
        service=installed_service_prod,
        version=prod_version,
        timestamp=previous_release_date + datetime.timedelta(days=4),
    )
    # current release
    prod_version = Version.objects.create(module=module, version='1.0')
    prod_installed_version = InstalledVersion.objects.create(
        service=installed_service_prod,
        version=prod_version,
        timestamp=upcoming_release_date,
    )

    repo = Repo.init(os.path.join(settings.MEDIA_ROOT, 'src/chrono/'))
    repo.index.commit('first commit')
    repo.create_tag('v0.1')
    repo.index.commit('add feature 1 (#42)')
    repo.create_tag('v1.0')
    repo.index.commit('add feature 2 (#1)')
    repo.index.commit('add feature 3 (#2)')
    repo.create_tag('v1.1')
    repo.index.commit('add feature 4 (#43)')

    resp = app.get('/')
    resp = resp.click('historique')

    releases = [x for x in resp.pyquery('#history-summary div')]
    assert resp.pyquery(releases[0])('h3').text() == 'À venir'
    assert resp.pyquery(releases[0])('span').text() == 'chrono (1.0 → 1.1)'
    assert resp.pyquery(releases[1])('h3').text() == upcoming_release_date.strftime('%d/%m/%Y')
    assert resp.pyquery(releases[1])('span').text() == 'chrono (0.1 → 1.0)'

    responses.add(
        responses.GET,
        'https://redmine.example.org/issues/1.json',
        json=CHRONO_ISSUE_1,
    )
    responses.add(
        responses.GET,
        'https://redmine.example.org/issues/2.json',
        json=CHRONO_ISSUE_2,
    )

    url = resp.pyquery('div#history-summary div')[0].attrib['data-issues-url-content']
    params = {
        'chrono': {
            'name': 'chrono',
            'current_version': '1.0',
            'previous_version': '1.1',
        }
    }
    resp = app.post_json(url, params=params)

    assert len(resp.pyquery('tr')) == 2
    assert 'https://redmine.example.org/issues/1' in resp.text
    assert 'https://redmine.example.org/issues/2' in resp.text
    assert 'TECH' not in resp.text
    # issue cannot be edited while logged out
    assert 'Editer' not in resp.text

    resp = app.get('/api/pending-issues/saas2/', params={'user_id': 42})
    assert resp.json['data'] == [{'id': '1', 'text': 'Fix bug'}]

    resp = app.get('/api/pending-issues/saas2/', params={'user_id': 43})
    assert resp.json['data'] == [{'id': '2', 'text': 'Improve code'}]

    app = login(app)
    resp = app.get('/projects/saas2/pending-issues')
    assert 'https://redmine.example.org/issues/1' in resp.text
    assert 'https://redmine.example.org/issues/2' in resp.text

    resp = app.get('/projects/saas2/pending-issues?user_id=42')
    assert 'https://redmine.example.org/issues/1' in resp.text
    assert 'https://redmine.example.org/issues/2' not in resp.text

    # issue can be edited when logged in
    resp = app.post_json(url, params=params)
    resp = resp.click('Editer', index=0)
    resp.form['issue_type'] = 'TECH'
    resp.form.submit().follow()

    resp = app.post_json(url, params=params)
    assert 'TECH' in resp.text

    resp = app.get('/api/pending-issues/saas2/', params={'user_id': 42})
    assert resp.json['data'] == []

    resp = app.get('/api/pending-issues/saas2/', params={'user_id': 43})
    assert resp.json['data'] == [{'id': '2', 'text': 'Improve code'}]

    resp = app.get('/projects/saas2/pending-issues')
    assert 'https://redmine.example.org/issues/1' not in resp.text
    assert 'https://redmine.example.org/issues/2' in resp.text

    resp = app.get('/projects/saas2/pending-issues?user_id=42')
    assert 'Aucun ticket' in resp.text
