import json
from datetime import datetime
from unittest.mock import patch

from django.contrib.auth.models import User
from django.core.management import call_command
from django.shortcuts import reverse
from django.test import Client, TestCase

from dataschema_manager.models import DataSchema
from experiments_manager.models import ChosenExperimentSteps, Experiment
from git_manager.models import GitRepository
from user_manager.models import WorkbenchUser


class QualityManagerTestCase(TestCase):
    def setUp(self):
        call_command('loaddata', 'fixtures/steps.json', verbosity=0)
        call_command('loaddata', 'fixtures/measures.json', verbosity=0)
        call_command('loaddata', 'fixtures/package_categories_languages.json', verbosity=0)
        call_command('loaddata', 'fixtures/cookiecutter.json', verbosity=0)

        self.user = User.objects.create_user('test', '<EMAIL>', 'test')
        self.workbench_user = WorkbenchUser.objects.get(user=self.user)

        self.second_user = User.objects.create_user('test2', '<EMAIL>', 'test2')
        self.git_repo = GitRepository.objects.create(name='Experiment', owner=self.workbench_user, github_url='https://github')
        schema = DataSchema(name='main')
        schema.save()
        self.experiment = Experiment.objects.create(title='Experiment',
                                                    description='test',
                                                    owner=self.workbench_user,
                                                    git_repo=self.git_repo,
                                                    language_id=1,
                                                    template_id=2,
                                                    schema=schema)
        self.chosen_experiment_step = ChosenExperimentSteps.objects.create(step_id=1,
                                                                           experiment=self.experiment,
                                                                           step_nr=1,
                                                                           active=True,
                                                                           location='/src/main/')

        self.client = Client()
        self.client.login(username='test', password='<PASSWORD>')

    def test_dashboard_view(self):
        response = self.client.get(reverse('dashboard', kwargs={'experiment_id': self.experiment.id}))
        self.assertEqual(response.status_code, 200)
        self.assertIsNotNone(response.context['messages'])

    @patch('quality_manager.views.DashboardView._get_recent_measurements_for_all_types')
    def test_dashboard_view_with_messages(self, mock_messages):
        mock_messages.return_value = [MeasurementMockClass(), MeasurementMockClass(), MeasurementMockClass()]
        response = self.client.get(reverse('dashboard', kwargs={'experiment_id': self.experiment.id}))
        self.assertEqual(response.status_code, 200)
        self.assertIsNotNone(response.context['dashboard_messages'])
        self.assertIsNotNone(response.context['dashboard_messages']['test_slug'])

    def test_vcs_overview(self):
        response = self.client.get(reverse('vcs_overview', kwargs={'experiment_id': self.experiment.id}))
        self.assertEqual(response.status_code, 200)

    @patch('quality_manager.views.get_nr_of_commits_last_week')
    def test_nr_of_commits_view(self, mock_recent_measurements):
        mock_recent_measurements.return_value = [5, 5, 5], [1, 2, 3]
        response = self.client.get(reverse('nr_of_commits', kwargs={'experiment_id': self.experiment.id}))
        self.assertEqual(response.status_code, 200)
        json_response = json.loads(str(response.content, encoding='utf8'))
        self.assertEqual(json_response['values'], [5, 5, 5])

    @patch('quality_manager.views.task_complete_quality_check')
    def test_refresh_measurements(self, mock_check):
        response = self.client.get(reverse('measurements_refresh', kwargs={'step_id': self.chosen_experiment_step.id}))
        self.assertEqual(response.status_code, 200)


class MeasurementMockClass(object):
    def __init__(self):
        self.measurement = MeasurementMessageMockClass()
        self.created = datetime.now()
        self.raw_values = MeasurementRawValue()

    def get_message(self):
        return 'Get to work fool!'

    def slug(self):
        return 'test_slug'


class MeasurementMessageMockClass(object):
    def __init__(self):
        self.name = 'My First Measurement'


class MeasurementRawValue(object):
    def all(self):
        return [RawValue()]


class RawValue(object):
    def __init__(self):
        self.value = '5'

import json
from datetime import datetime
from unittest.mock import patch

from django.contrib.auth.models import User
from django.core.management import call_command
from django.shortcuts import reverse
from django.test import Client, TestCase

from dataschema_manager.models import DataSchema
from experiments_manager.models import ChosenExperimentSteps, Experiment
from git_manager.models import GitRepository
from user_manager.models import WorkbenchUser


class QualityManagerTestCase(TestCase):
    def setUp(self):
        call_command('loaddata', 'fixtures/steps.json', verbosity=0)
        call_command('loaddata', 'fixtures/measures.json', verbosity=0)
        call_command('loaddata', 'fixtures/package_categories_languages.json', verbosity=0)
        call_command('loaddata', 'fixtures/cookiecutter.json', verbosity=0)

        self.user = User.objects.create_user('test', '<EMAIL>', 'test')
        self.workbench_user = WorkbenchUser.objects.get(user=self.user)

        self.second_user = User.objects.create_user('test2', '<EMAIL>', 'test2')
        self.git_repo = GitRepository.objects.create(name='Experiment', owner=self.workbench_user, github_url='https://github')
        schema = DataSchema(name='main')
        schema.save()
        self.experiment = Experiment.objects.create(title='Experiment',
                                                    description='test',
                                                    owner=self.workbench_user,
                                                    git_repo=self.git_repo,
                                                    language_id=1,
                                                    template_id=2,
                                                    schema=schema)
        self.chosen_experiment_step = ChosenExperimentSteps.objects.create(step_id=1,
                                                                           experiment=self.experiment,
                                                                           step_nr=1,
                                                                           active=True,
                                                                           location='/src/main/')

        self.client = Client()
        self.client.login(username='test', password='<PASSWORD>')

    def test_dashboard_view(self):
        response = self.client.get(reverse('dashboard', kwargs={'experiment_id': self.experiment.id}))
        self.assertEqual(response.status_code, 200)
        self.assertIsNotNone(response.context['messages'])

    @patch('quality_manager.views.DashboardView._get_recent_measurements_for_all_types')
    def test_dashboard_view_with_messages(self, mock_messages):
        mock_messages.return_value = [MeasurementMockClass(), MeasurementMockClass(), MeasurementMockClass()]
        response = self.client.get(reverse('dashboard', kwargs={'experiment_id': self.experiment.id}))
        self.assertEqual(response.status_code, 200)
        self.assertIsNotNone(response.context['dashboard_messages'])
        self.assertIsNotNone(response.context['dashboard_messages']['test_slug'])

    def test_vcs_overview(self):
        response = self.client.get(reverse('vcs_overview', kwargs={'experiment_id': self.experiment.id}))
        self.assertEqual(response.status_code, 200)

    @patch('quality_manager.views.get_nr_of_commits_last_week')
    def test_nr_of_commits_view(self, mock_recent_measurements):
        mock_recent_measurements.return_value = [5, 5, 5], [1, 2, 3]
        response = self.client.get(reverse('nr_of_commits', kwargs={'experiment_id': self.experiment.id}))
        self.assertEqual(response.status_code, 200)
        json_response = json.loads(str(response.content, encoding='utf8'))
        self.assertEqual(json_response['values'], [5, 5, 5])

    @patch('quality_manager.views.task_complete_quality_check')
    def test_refresh_measurements(self, mock_check):
        response = self.client.get(reverse('measurements_refresh', kwargs={'step_id': self.chosen_experiment_step.id}))
        self.assertEqual(response.status_code, 200)


class MeasurementMockClass(object):
    def __init__(self):
        self.measurement = MeasurementMessageMockClass()
        self.created = datetime.now()
        self.raw_values = MeasurementRawValue()

    def get_message(self):
        return 'Get to work fool!'

    def slug(self):
        return 'test_slug'


class MeasurementMessageMockClass(object):
    def __init__(self):
        self.name = 'My First Measurement'


class MeasurementRawValue(object):
    def all(self):
        return [RawValue()]


class RawValue(object):
    def __init__(self):
        self.value = '5'
