# -*- coding: utf-8 -*-
#
# ITerativ GmbH
# http://www.iterativ.ch/
#
# Copyright (c) 2019 ITerativ GmbH. All rights reserved.
#
# Created on 2019-11-13
# @author: chrigu <christian.cueni@iterativ.ch>

from graphql_relay import to_global_id

from api.test_utils import create_client, DefaultUserTestCase
from assignments.models import Assignment, StudentSubmission
from core.tests.base_test import SkillboxTestCase
from users.factories import SchoolClassFactory
from users.models import SchoolClassMember
from .queries.mutations import UPDATE_SUBMISSION_FEEDBACK_MUTATION
from ..factories import AssignmentFactory, StudentSubmissionFactory, SubmissionFeedbackFactory


class SubmissionFeedbackTestCase(SkillboxTestCase):
    def setUp(self):
        self.createDefault()

        self.assignment = AssignmentFactory(
            owner=self.teacher
        )
        self.assignment_id = to_global_id('AssignmentNode', self.assignment.pk)

        self.student_submission = StudentSubmissionFactory(assignment=self.assignment, student=self.student1,
                                                           final=False)
        self.student_submission_id = to_global_id('StudentSubmissionNode', self.student_submission.pk)

        school_class = SchoolClassFactory()
        for user in [self.student1, self.teacher, self.teacher2]:
            SchoolClassMember.objects.create(
                user=user,
                school_class=school_class
            )

    def _create_submission_feedback(self, user, final, text, student_submission_id):
        return self.get_client(user).execute(UPDATE_SUBMISSION_FEEDBACK_MUTATION, variables={
            'input': {
                "submissionFeedback": {
                    "studentSubmission": student_submission_id,
                    "text": text,
                    "final": final
                }
            }
        })

    def _fetch_assignment_student(self, user):
        client = create_client(user)
        query = '''
            query AssignmentWithSubmissions($id: ID!) {
              assignment(id: $id) {
                title
                submission {
                  id
                  text
                  document
                  submissionFeedback {
                    text
                  }
                }
              }
            }
        '''
        return client.execute(query, variables={
            'id': self.assignment_id
        })

    def _fetch_assignment_teacher(self, user):
        client = create_client(user)
        query = '''
            query AssignmentWithSubmissions($id: ID!) {
              assignment(id: $id) {
                title
                submissions {
                  id
                  text
                  document
                  submissionFeedback {
                    text
                  }
                }
              }
            }
        '''
        return client.execute(query, variables={
            'id': self.assignment_id
        })

    def _fetch_submission_feedback(self, user):
        client = create_client(user)
        query = '''
            query AssignmentWithSubmissions($id: ID!) {
              assignment(id: $id) {
                title
                submissions {
                  id
                  text
                  document
                  submissionFeedback {
                    text
                  }
                }
              }
            }
        '''
        return client.execute(query, variables={
            'id': self.assignment_id
        })

    def test_teacher_can_create_feedback(self):
        result = self._create_submission_feedback(self.teacher, False, 'Balalal', self.student_submission_id)

        self.assertIsNone(result.get('errors'))
        self.assertIsNotNone(
            result.get('data').get('updateSubmissionFeedback').get('updatedSubmissionFeedback').get('id'))

    def test_student_cannot_create_feedback(self):
        result = self._create_submission_feedback(self.student1, False, 'Balalal', self.student_submission_id)
        self.assertIsNotNone(result.get('errors'))

    def test_teacher_can_update_feedback(self):
        assignment = AssignmentFactory(
            owner=self.teacher
        )

        student_submission = StudentSubmissionFactory(assignment=assignment, student=self.student1, final=False)
        submission_feedback = SubmissionFeedbackFactory(teacher=self.teacher, final=False,
                                                        student_submission=student_submission)
        submission_feedback_id = to_global_id('SubmissionFeedback', submission_feedback.pk)

        result = self._create_submission_feedback(self.teacher, True, 'Some', submission_feedback_id)

        self.assertIsNone(result.get('errors'))

        submission_feedback_response = result.get('data').get('updateSubmissionFeedback').get(
            'updatedSubmissionFeedback')

        self.assertTrue(submission_feedback_response.get('final'))
        self.assertEqual(submission_feedback_response.get('text'), 'Some')

    def test_rogue_teacher_cannot_update_feedback(self):
        assignment = AssignmentFactory(
            owner=self.teacher
        )

        student_submission = StudentSubmissionFactory(assignment=assignment, student=self.student1, final=False)
        submission_feedback = SubmissionFeedbackFactory(teacher=self.teacher, final=False,
                                                        student_submission=student_submission)
        submission_feedback_id = to_global_id('SubmissionFeedback', submission_feedback.pk)

        result = self._create_submission_feedback(self.teacher2, True, 'Some', submission_feedback_id)

        self.assertIsNotNone(result.get('errors'))

    def test_student_does_not_see_non_final_feedback(self):
        SubmissionFeedbackFactory(teacher=self.teacher, final=False, student_submission=self.student_submission)
        result = self._fetch_assignment_student(self.student1)

        self.assertIsNone(result.get('data').get('submissionFeedback'))

    def test_student_does_see_final_feedback(self):
        submission_feedback = SubmissionFeedbackFactory(teacher=self.teacher, final=True,
                                                        student_submission=self.student_submission)
        result = self._fetch_assignment_student(self.student1)
        self.assertEqual(result.get('data').get('assignment').get('submission').get('submissionFeedback')
                         .get('text'), submission_feedback.text)

    def test_teacher_can_see_feedback_for_submission(self):
        submission_feedback = SubmissionFeedbackFactory(teacher=self.teacher, final=False,
                                                        student_submission=self.student_submission)
        self.student_submission.final = True
        self.student_submission.save()

        result = self._fetch_assignment_teacher(self.teacher)
        self.assertEqual(result.get('data').get('assignment').get('submissions')[0].get('submissionFeedback')
                         .get('text'), submission_feedback.text)

    def test_rogue_teacher_cannot_see_feedback(self):
        SubmissionFeedbackFactory(teacher=self.teacher, final=False,
                                  student_submission=self.student_submission)
        self.student_submission.final = True
        self.student_submission.save()

        result = self._fetch_assignment_teacher(self.teacher2)
        self.assertIsNone(result.get('data').get('assignment').get('submissions')[0].get('submissionFeedback'))
