# from django.core.validators import MinValueValidator, MaxValueValidator
# from rest_framework import serializers
#
# from authenticate.serializers import PublicUserSerializer
# from exam import conf, validators
# from exam.models import ExamTemplate, Exam, Corrections, REPORT_CARD_STRATEGY_ON_DATE_TIME, ExamPage, AnswerFile
# from exam.validators import exam_rule_validator, report_card_strategy_validator, exam_sort_by_validator, \
#     user_inputs_validator
# from institute.serializers import SafeInstituteSerializerForExam, InstituteSerializerForExamAndInstituteAndQuestionBank, \
#     InstituteStudentSerializerForExamStat
# from question.models import QUESTION_TYPE_MULTIPLE_CHOICE, QUESTION_TYPE_DESCRIPTIVE
# from utils import validators as main_validators
# from utils.validators import IncludeExcludeOnlyValidator
#
# exam_template_list_fields = ['id', 'name', 'description', 'duration', 'report_card_strategy', 'institute', 'override_institute_name',
#                              'override_institute_logo', 'examiner_info_visibility', 'theme', 'questions_count', 'poster', 'created_at', 'modified_at']
#
#
# # TODO add apply_negative_scores_filter to list APIs
#
# def rules_lazy_loading_helper(obj):
#     # obj can be exam, exam_template, or public_exam_template
#     # I'm disabling this mask for now, we will ned the number of questions, scores, ... which can only be calculated from questions data
#     # for group in obj.rules['groups']:
#     #     group.pop('questions')
#     pass
#
#
# class ExamTemplateListSerializer(serializers.ModelSerializer):
#     institute = InstituteSerializerForExamAndInstituteAndQuestionBank()
#
#     class Meta:
#         model = ExamTemplate
#         fields = exam_template_list_fields
#
#
# class ExamTemplateGetSerializer(serializers.ModelSerializer):
#     institute = InstituteSerializerForExamAndInstituteAndQuestionBank()
#     rules = serializers.SerializerMethodField('lazy_loading_rules')
#
#     class Meta:
#         model = ExamTemplate
#         fields = exam_template_list_fields + ['rules', 'shuffle_questions', 'shuffle_answers', 'one_question_at_a_time', 'reanswer',
#                                               'apply_negative_scores']
#
#     def lazy_loading_rules(self, exam_template):
#         rules_lazy_loading_helper(exam_template)
#         return exam_template.rules
#
#
# public_exam_template_list_fields = ['id', 'name', 'description',
#                                     'duration', 'report_card_strategy', 'theme', 'questions_count', 'poster']
#
#
# class PublicExamTemplateListSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = ExamTemplate
#         fields = public_exam_template_list_fields
#
#
# class PublicExamTemplateGetSerializer(serializers.ModelSerializer):
#     rules = serializers.SerializerMethodField('lazy_loading_rules')
#
#     class Meta:
#         model = ExamTemplate
#         fields = public_exam_template_list_fields + ['rules', 'shuffle_questions', 'shuffle_answers', 'one_question_at_a_time', 'reanswer',
#                                                      'apply_negative_scores', 'poster']
#
#     def lazy_loading_rules(self, public_template):
#         rules_lazy_loading_helper(public_template)
#         return public_template.rules
#
#
# class ListExamValidatorInputSerializer(serializers.Serializer):
#     # when we are using api_key, the institute_id is not required
#     # TODO check for security issues here
#     institute_id = serializers.CharField(required=False)
#     q = serializers.CharField(max_length=100, required=False, allow_null=True)
#     skip = serializers.IntegerField(validators=[MinValueValidator(0)])
#     take = serializers.IntegerField(
#         validators=[MinValueValidator(1), MaxValueValidator(100)])
#     sort_by = serializers.CharField(validators=[exam_sort_by_validator])
#     active_filter = serializers.CharField(required=False, validators=[
#                                           main_validators.active_filter_validator])
#     reanswer_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#     shuffle_questions_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#     shuffle_answers_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#     one_question_at_a_time_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#     deleted_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#
#
# class CreateExamInputSerializer(serializers.Serializer):
#     # TODO: to add token here or decorate tne new middleware on its function
#     context_institute_id = serializers.CharField()
#     name = serializers.CharField()
#     rules = serializers.JSONField()
#     one_question_at_a_time = serializers.BooleanField()
#     public = serializers.BooleanField()
#     reanswer = serializers.BooleanField()
#     report_card_strategy = serializers.CharField(
#         max_length=20, validators=[report_card_strategy_validator])
#     report_card_date = serializers.DateTimeField(
#         required=False, allow_null=True)
#     shuffle_questions = serializers.BooleanField()
#     shuffle_answers = serializers.BooleanField()
#     apply_negative_scores = serializers.BooleanField()
#     examiner_info_visibility = serializers.BooleanField()
#     override_institute_name = serializers.CharField(required=False)
#     # TODO move image_validator out of authenticate app
#     override_institute_logo = serializers.ImageField(required=False)
#     poster = serializers.ImageField(required=False)
#     start_date = serializers.DateTimeField(required=False)
#     end_date = serializers.DateTimeField(required=False)
#     duration = serializers.DurationField(required=False)
#     description = serializers.CharField(max_length=3000, required=False)
#     theme = serializers.CharField(max_length=20)
#     create_exam_template = serializers.BooleanField(required=False)
#     delayable = serializers.BooleanField()
#     max_delay = serializers.DurationField(required=False)
#     # 34567534678
#     # Because min_value = 0, default = 0 price will never be null
#     price = serializers.IntegerField(required=False, min_value=0, default=0)
#     finish_message = serializers.CharField(required=False, max_length=1000)
#
#     def validate_override_institute_logo(self, value):
#         main_validators.image_validetor(image=value, image_size_as_MB=conf.maximum_size_for_exam_override_institute_logo, format=conf.allowed_formats_for_exam_override_institute_logo,
#                                         max_side=conf.maximum_side_size_for_exam_override_institute_logo)
#         return value
#
#     def validate_poster(self, value):
#         main_validators.image_validetor(image=value, image_size_as_MB=conf.maximum_size_for_exam_poster, format=conf.allowed_formats_for_exam_poster,
#                                         max_side=conf.maximum_side_size_for_exam_poster)
#         return value
#
#     def validate_name(self, value):
#         main_validators.name_validator(
#             name=value, min_length=3, max_length=100)
#         return value
#
#     def validate_override_institute_name(self, value):
#         main_validators.name_validator(
#             name=value, min_length=3, max_length=100)
#         return value
#
#     # TODO add test for this validation
#     def validate(self, data):
#         if 'report_card_strategy' in data and data['report_card_strategy'] == REPORT_CARD_STRATEGY_ON_DATE_TIME:
#             if 'report_card_date' not in data or data['report_card_strategy'] is None:
#                 raise serializers.ValidationError({
#                     'report_card_date': 'report_card_date is required when report_card_strategy="' + REPORT_CARD_STRATEGY_ON_DATE_TIME + '"'})
#         if 'delayable' in data and data['delayable'] is True:
#             if 'max_delay' not in data or data['max_delay'] is None:
#                 raise serializers.ValidationError(
#                     {'max_delay': 'max_delay is required when delayable=True'})
#
#         exam_rule_validator(data['rules'])
#         return data
#
#
# class GetExamInputSerializer(serializers.Serializer):
#     exam_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#
#
# class EditExamInputSerializer(serializers.Serializer):
#     exam_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#     name = serializers.CharField(required=False)
#     rules = serializers.JSONField(required=False)
#     one_question_at_a_time = serializers.BooleanField(required=False)
#     public = serializers.BooleanField(required=False)
#     reanswer = serializers.BooleanField(required=False)
#     report_card_strategy = serializers.CharField(
#         max_length=20, validators=[report_card_strategy_validator], required=False)
#     report_card_date = serializers.DateTimeField(required=False)
#     shuffle_questions = serializers.BooleanField(required=False)
#     shuffle_answers = serializers.BooleanField(required=False)
#     apply_negative_scores = serializers.BooleanField(required=False)
#
#     examiner_info_visibility = serializers.BooleanField(required=False)
#     override_institute_name = serializers.CharField(
#         max_length=100, required=False, allow_blank=True, allow_null=True)
#     # TODO move image_validator out of authenticate app
#     override_institute_logo = serializers.ImageField(required=False)
#     delete_override_institute_logo = serializers.BooleanField(required=False)
#     poster = serializers.ImageField(required=False)
#     delete_poster = serializers.BooleanField(default=False)
#     start_date = serializers.DateTimeField(required=False)
#     end_date = serializers.DateTimeField(required=False)
#     duration = serializers.DurationField(required=False)
#     delayable = serializers.BooleanField(required=False)
#     max_delay = serializers.DurationField(required=False)
#     description = serializers.CharField(max_length=3000, required=False)
#     theme = serializers.CharField(max_length=20, required=False)
#     price = serializers.IntegerField(
#         required=False, min_value=0, allow_null=True)
#     finish_message = serializers.CharField(required=False, max_length=1000)
#
#     def validate_override_institute_logo(self, value):
#         main_validators.image_validetor(image=value, image_size_as_MB=conf.maximum_size_for_exam_override_institute_logo, format=conf.allowed_formats_for_exam_override_institute_logo,
#                                         max_side=conf.maximum_side_size_for_exam_override_institute_logo)
#         return value
#
#     def validate_poster(self, value):
#         main_validators.image_validetor(image=value, image_size_as_MB=conf.maximum_size_for_exam_poster, format=conf.allowed_formats_for_exam_poster,
#                                         max_side=conf.maximum_side_size_for_exam_poster)
#         return value
#
#     def validate_name(self, value):
#         main_validators.name_validator(
#             name=value, min_length=3, max_length=100)
#         return value
#
#     def validate_override_institute_name(self, value):
#         # None is allowed
#         if value is None:
#             return None
#         # '' is allowed
#         if value == '':
#             return ''
#         main_validators.name_validator(
#             name=value, min_length=3, max_length=100)
#         return value
#
#     def validate(self, data):
#         if 'report_card_strategy' in data and data['report_card_strategy'] == REPORT_CARD_STRATEGY_ON_DATE_TIME:
#             if 'report_card_date' not in data or data['report_card_date'] is None:
#                 raise serializers.ValidationError({
#                     'report_card_date': 'report_card_date is required when report_card_strategy="' + REPORT_CARD_STRATEGY_ON_DATE_TIME + '"'})
#         if (('one_question_at_a_time' in data and data['one_question_at_a_time'] != None) and (
#                 'reanswer' not in data or data['reanswer'] == None)) or (
#                 ('reanswer' in data and data['reanswer'] != None) and (
#                 'one_question_at_a_time' not in data or data['one_question_at_a_time'] == None)):
#             raise serializers.ValidationError(
#                 'if one of one_question_at_a_time or reanswer was sent, the other one should also be sent')
#         if 'rules' in data and data['rules'] != None:
#             exam_rule_validator(data['rules'])
#         if 'delayable' in data and data['delayable'] is True:
#             if 'max_delay' not in data or data['max_delay'] is None:
#                 raise serializers.ValidationError(
#                     {'max_delay': 'max_delay is required when delayable=True'})
#         return data
#
#
# class DeleteExamInputSerializer(serializers.Serializer):
#     exam_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#
#
# class ExamGroupGetInputValidator(serializers.Serializer):
#     exam_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#     group_id = serializers.IntegerField()
#
#
# class ExamGroupStatInputValidator(serializers.Serializer):
#     exam_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#
#
# class ExamTemplateGroupGetInputValidator(serializers.Serializer):
#     exam_template_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#     group_id = serializers.IntegerField()
#
#
# class InstituteStudentGetQuestionExamPageInputSerializer(serializers.Serializer):
#     group_index = serializers.IntegerField()
#     question_index = serializers.IntegerField()
#
#
# class CreateExamTemplateInputSerializer(serializers.Serializer):
#     exam_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#
#
# class EditExamTemplateInputSerializer(serializers.Serializer):
#     exam_template_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#     name = serializers.CharField(required=False)
#     rules = serializers.JSONField(required=False)
#     one_question_at_a_time = serializers.BooleanField(required=False)
#     reanswer = serializers.BooleanField(required=False)
#     report_card_strategy = serializers.CharField(
#         max_length=20, validators=[report_card_strategy_validator], required=False)
#     shuffle_questions = serializers.BooleanField(required=False)
#     shuffle_answers = serializers.BooleanField(required=False)
#     apply_negative_scores = serializers.BooleanField(required=False)
#     examiner_info_visibility = serializers.BooleanField(required=False)
#     override_institute_name = serializers.CharField(
#         max_length=100, required=False, allow_blank=True)
#     override_institute_logo = serializers.ImageField(required=False)
#     theme = serializers.CharField(max_length=20, required=False)
#     description = serializers.CharField(max_length=3000, required=False)
#     duration = serializers.DurationField(required=False)
#     delayable = serializers.BooleanField(required=False)
#     price = serializers.IntegerField(required=False, min_value=0)
#     max_delay = serializers.DurationField(required=False)
#     finish_message = serializers.CharField(required=False, max_length=1000)
#     poster = serializers.ImageField(required=False)
#     delete_poster = serializers.BooleanField(required=False)
#
#     def validate_override_institute_logo(self, value):
#         main_validators.image_validetor(image=value, image_size_as_MB=conf.maximum_size_for_exam_override_institute_logo, format=conf.allowed_formats_for_exam_override_institute_logo,
#                                         max_side=conf.maximum_side_size_for_exam_override_institute_logo)
#         return value
#
#     def validate_name(self, value):
#         main_validators.name_validator(
#             name=value, min_length=3, max_length=100)
#         return value
#
#     def validate_override_institute_name(self, value):
#         main_validators.name_validator(
#             name=value, min_length=3, max_length=100)
#         return value
#
#     def validate(self, data):
#         if 'report_card_strategy' in data and data['report_card_strategy'] == REPORT_CARD_STRATEGY_ON_DATE_TIME:
#             if 'report_card_date' not in data or data['report_card_date'] is None:
#                 raise serializers.ValidationError({
#                     'report_card_date': 'report_card_date is required when report_card_strategy="' + REPORT_CARD_STRATEGY_ON_DATE_TIME + '"'})
#         if (('one_question_at_a_time' in data and data['one_question_at_a_time'] != None) and (
#                 'reanswer' not in data or data['reanswer'] == None)) or (
#                 ('reanswer' in data and data['reanswer'] != None) and (
#                 'one_question_at_a_time' not in data or data['one_question_at_a_time'] == None)):
#             raise serializers.ValidationError(
#                 'if one of one_question_at_a_time or reanswer was sent, the other one should also be sent')
#         if 'rules' in data and data['rules'] != None:
#             exam_rule_validator(data['rules'])
#
#         if 'delayable' in data and data['delayable'] is True:
#             if 'max_delay' not in data or data['max_delay'] is None:
#                 raise serializers.ValidationError(
#                     {'max_delay': 'max_delay is required when delayable=True'})
#         return data
#
#
# class GetExamTemplateInputSerializer(serializers.Serializer):
#     exam_template_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#
#
# class GetPublicExamTemplateInputSerializer(serializers.Serializer):
#     public_exam_template_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#
#
# class ListPublicExamTemplateInputSerializer(serializers.Serializer):
#     skip = serializers.IntegerField(validators=[MinValueValidator(0)])
#     take = serializers.IntegerField(
#         validators=[MinValueValidator(1), MaxValueValidator(100)])
#     q = serializers.CharField(max_length=100, required=False)
#     one_question_at_a_time_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#     reanswer_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#     shuffle_questions_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#     shuffle_answers_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#
#
# class ListExamTemplateInputSerializer(serializers.Serializer):
#     institute_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#     skip = serializers.IntegerField(validators=[MinValueValidator(0)])
#     take = serializers.IntegerField(
#         validators=[MinValueValidator(1), MaxValueValidator(100)])
#     q = serializers.CharField(max_length=100, required=False, allow_null=True)
#     reanswer_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#     shuffle_questions_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#     shuffle_answers_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#     one_question_at_a_time_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#     deleted_filter = serializers.CharField(
#         validators=[IncludeExcludeOnlyValidator()])
#
#
# class DeleteExamTemplateInputSerializer(serializers.Serializer):
#     exam_template_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#
#
# class GetExamSerializer(serializers.ModelSerializer):
#     institute = InstituteSerializerForExamAndInstituteAndQuestionBank()
#     rules = serializers.SerializerMethodField('lazy_loading_rules')
#
#     class Meta:
#         model = Exam
#         fields = ['id', 'name', 'start_date', 'end_date', 'duration', 'public', 'public_id', 'one_question_at_a_time', 'reanswer',
#                   'report_card_strategy', 'report_card_date', 'delayable', 'max_delay', 'shuffle_questions', 'generated_exam', 'rules',
#                   'shuffle_answers', 'override_institute_name', 'override_institute_logo', 'examiner_info_visibility', 'description',
#                   'theme', 'poster', 'poster_thumbnail', 'questions_count', 'created_at', 'modified_at', 'apply_negative_scores',
#                   'institute', 'price', 'finish_message']
#
#     def lazy_loading_rules(self, exam):
#         rules_lazy_loading_helper(exam)
#         return exam.rules
#
#
# class ListExamSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = Exam
#         fields = ['id', 'name', 'start_date', 'end_date', 'duration', 'public', 'public_id', 'one_question_at_a_time',
#                   'reanswer', 'report_card_strategy', 'report_card_date', 'shuffle_questions', 'shuffle_answers',
#                   'override_institute_name', 'override_institute_logo', 'description', 'created_at', 'modified_at']
#
#
# class GetExamSerializerForCoverPage(serializers.ModelSerializer):
#     institute = InstituteSerializerForExamAndInstituteAndQuestionBank()
#
#     class Meta:
#         model = Exam
#         fields = ['id', 'name', 'description', 'start_date', 'end_date', 'duration', 'report_card_strategy', 'report_card_date',
#                   'institute', 'override_institute_name', 'override_institute_logo', 'examiner_info_visibility', 'apply_negative_scores',
#                   'poster', 'poster_thumbnail',
#                   'questions_count', 'reanswer', 'one_question_at_a_time', 'theme', 'created_at', 'modified_at', 'price']
#
#
# class GetExamSerializerForEnterPage(serializers.ModelSerializer):
#     class Meta:
#         model = Exam
#         fields = ['name', 'description', 'theme']
#
#
# class StartExamPageInputSerializer(serializers.Serializer):
#     exam_page_id = serializers.CharField()
#
#
# class GetCorrectionsForStudentSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = Corrections
#         fields = ['question', 'score', 'comment_for_student']
#
#
# class GetCorrectionsForCorrectorSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = Corrections
#         fields = ['question', 'score', 'comment_for_student',
#                   'comment_for_other_correctors', 'created_at', 'modified_at']
#
#
# class CorrectionsForExamStat(serializers.ModelSerializer):
#     class Meta:
#         model = Corrections
#         fields = ['question_id', 'score', 'blank']
#
#
# class GetPublicExamPageInputSerializer(serializers.Serializer):
#     public_id = serializers.CharField()
#
#
# class GetPublicExamSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = Exam
#         fields = ['id', 'name', 'start_date', 'end_date', 'duration', 'override_institute_name', 'override_institute_logo', 'description',
#                   'created_at', 'modified_at']
#
#
# class GenerateExamPageInputValidator(serializers.Serializer):
#     wikiazma_institute_student_id = serializers.CharField(required=False)
#     referer_institute_student_identity = serializers.CharField(required=False)
#     wikiazma_exam_id = serializers.CharField()
#     start_date = serializers.DateTimeField(required=False)
#     end_date = serializers.DateTimeField(required=False)
#     duration = serializers.DurationField(required=False)
#     delayable = serializers.BooleanField()
#
#     def validate(self, data):
#         """
#         One out of many fields should be present.
#         """
#         fields = ['wikiazma_institute_student_id',
#                   'referer_institute_student_identity']
#         one_field_found = False
#         for field in fields:
#             if field in data:
#                 if one_field_found:
#                     raise serializers.ValidationError(
#                         "One of " + ' and '.join(fields) + " is required.")
#                 one_field_found = True
#         return data
#
#
# minimum_exam_page_fields = ['id', 'state', 'entrance_date', 'start_date', 'end_date', 'duration', 'questions_count',
#                             'apply_negative_scores', 'one_question_at_a_time', 'reanswer']
#
#
# class GetExamPageMinimumDataForStudentsSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = ExamPage
#         fields = minimum_exam_page_fields
#
#
# class GetExamPageMinimumDataPlusFirstAvailableIndexesForStudentsSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = ExamPage
#         fields = minimum_exam_page_fields + \
#             ['first_available_question_index', 'first_available_group_index']
#
#
# class GetExamPageFullDataIncludingEntranceTokenSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = ExamPage
#         fields = minimum_exam_page_fields + \
#             ['entrance_token', 'generated_exam', 'user_inputs', 'final_score']
#
#
# class GetExamPageBeforeScoresPublishedSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = ExamPage
#         fields = minimum_exam_page_fields + []
#
#
# class GetExamPageAfterScoresPublishedSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = ExamPage
#         fields = minimum_exam_page_fields + \
#             ['generated_exam', 'user_inputs', 'final_score', 'report_card']
#
#
# class GetExamPageWithRestrictedGeneratedExamForStudentsSerializer(serializers.ModelSerializer):
#     generated_exam = serializers.SerializerMethodField(
#         'restrict_and_secure_generated_exam')
#
#     class Meta:
#         model = ExamPage
#         fields = minimum_exam_page_fields + ['generated_exam']
#
#     # this is important otherwise the correct_answer will be sent to users before the exam
#     # this function has been tested in # TEST ID 84629056
#     def restrict_and_secure_generated_exam(self, exam_page):
#         for group in exam_page.generated_exam['groups']:
#             remove_sensitive_data_from_group_for_students(group)
#             for question in group['questions']:
#                 remove_sensitive_data_from_question_for_students(question)
#                 # securely_add_user_inputs_to_question(question, exam_page.user_inputs, only_user_input_status=True)
#                 securely_inject_user_inputs_with_attachments_to_question_instance(group_index=group['index'],
#                                                                                   question_index=question['index'],
#                                                                                   origin_question=question, exam_page=exam_page,
#                                                                                   only_user_input_status=True)
#                 remove_question_text_data_from_question_for_students(question)
#         return exam_page.generated_exam
#
#
# class GetExamPageOnAttendNotReanswerableExamSerializer(serializers.ModelSerializer):
#     generated_exam = serializers.SerializerMethodField(
#         'restrict_and_secure_generated_exam')
#
#     class Meta:
#         model = ExamPage
#         fields = minimum_exam_page_fields + \
#             ['generated_exam', 'first_available_question_index',
#                 'first_available_group_index']
#
#     # this is important otherwise the correct_answer will be sent to users before the exam
#     # this function has been tested in # TEST ID 84629056
#     def restrict_and_secure_generated_exam(self, exam_page):
#         for group in exam_page.generated_exam['groups']:
#             remove_sensitive_data_from_group_for_students(group)
#             for question in group['questions']:
#                 remove_sensitive_data_from_question_for_students(question)
#                 # securely_add_user_inputs_to_question(question, exam_page.user_inputs, only_user_input_status=True)
#                 securely_inject_user_inputs_with_attachments_to_question_instance(group_index=group['index'],
#                                                                                   question_index=question['index'],
#                                                                                   origin_question=question, exam_page=exam_page,
#                                                                                   only_user_input_status=True)
#                 remove_question_text_data_from_question_for_students(question)
#         return exam_page.generated_exam
#
#
# # def securely_add_user_inputs_to_question(question, user_inputs, only_user_input_status):
# #     user_input_found = False
# #     for user_input in user_inputs:
# #         if question['index'] == user_input['question_index']:
# #             if not only_user_input_status:
# #                 question['user_input'] = user_input
# #             question['user_input_status'] = "submitted"
# #             # TODO question['user_input_status'] = "blank"
# #             user_input_found = True
# #             break
# #     if not user_input_found:
# #         if not only_user_input_status:
# #             question['user_input'] = None
# #         question['user_input_status'] = "not_submitted"
#
#
# def securely_inject_user_inputs_with_attachments_to_question_instance(group_index, question_index, origin_question, exam_page,
#                                                                       only_user_input_status):
#     user_input_found = False
#     for user_input in exam_page.user_inputs:
#         if group_index == user_input['group_index'] and question_index == user_input['question_index']:
#             if not only_user_input_status:
#                 if origin_question['question_type'] == QUESTION_TYPE_DESCRIPTIVE:
#                     attachments = AnswerFile.objects.filter(
#                         exam_page=exam_page, group_index=group_index, question_index=question_index)
#                     user_input["attachments"] = GetAnswerFileModelSerializer(
#                         attachments, many=True).data
#                 origin_question['user_input'] = user_input
#             origin_question['user_input_status'] = "submitted"
#             # TODO question['user_input_status'] = "blank"
#             user_input_found = True
#             break
#     if not user_input_found:
#         if not only_user_input_status:
#             origin_question['user_input'] = None
#         origin_question['user_input_status'] = "not_submitted"
#
#
# class GetExamPageOnAttendAllQuestionsTogetherSerializer(serializers.ModelSerializer):
#     generated_exam = serializers.SerializerMethodField(
#         'generate_secure_generated_exam')
#
#     class Meta:
#         model = ExamPage
#         fields = minimum_exam_page_fields + \
#             ['generated_exam', 'first_available_question_index',
#                 'first_available_group_index']
#
#     # this is important otherwise the correct_answer will be sent to users before the exam
#     # this function has been tested in # TEST ID 84629056
#     def generate_secure_generated_exam(self, exam_page):
#         for group in exam_page.generated_exam['groups']:
#             remove_sensitive_data_from_group_for_students(group)
#             for question in group['questions']:
#                 remove_sensitive_data_from_question_for_students(question)
#                 # securely_add_user_inputs_to_question(question, exam_page.user_inputs, only_user_input_status=False)
#                 securely_inject_user_inputs_with_attachments_to_question_instance(group_index=group['index'],
#                                                                                   question_index=question['index'],
#                                                                                   origin_question=question, exam_page=exam_page,
#                                                                                   only_user_input_status=False)
#
#         return exam_page.generated_exam
#
#
# def remove_sensitive_data_from_group_for_students(group):
#     if 'id' in group:
#         group.pop('id')
#     # group.pop('priority')
#
#
# def remove_sensitive_data_from_question_for_students(question):
#     question.pop('question_id')
#     if 'solution' in question:
#         question.pop('solution')
#     if question['question_type'] == QUESTION_TYPE_MULTIPLE_CHOICE:
#         for choice in question['answer_rules']['choices']:
#             choice.pop('id')
#             choice.pop('is_correct_choice')
#     elif question['question_type'] == QUESTION_TYPE_DESCRIPTIVE:
#         # there is no sensitive information in descriptive question's answer_rules
#         pass
#     else:
#         # TODO secure other question types
#         pass
#
#
# def remove_question_text_data_from_question_for_students(question):
#     question.pop('question_text')
#     question.pop('question_text_format')
#     question.pop('answer_rules')
#     question.pop('question_type')
#
#
# class GetExamPageForStat(serializers.ModelSerializer):
#     user = PublicUserSerializer()
#     institute_student = InstituteStudentSerializerForExamStat()
#     corrections = serializers.SerializerMethodField('corrections_generator')
#
#     class Meta:
#         model = ExamPage
#         fields = ['id', 'final_score', 'state', 'entrance_date', 'report_card',
#                   'user', 'institute_student', 'corrections', 'finished_at']
#
#     def corrections_generator(self, exam_page):
#         corrections = Corrections.objects.filter(exam_page=exam_page)
#         return CorrectionsForExamStat(corrections, many=True).data
#
#
# class InstituteStudentSetAnswerExamPageInputSerializer(serializers.Serializer):
#     user_inputs = serializers.JSONField(required=False)
#     go_to_next_question = serializers.BooleanField()
#
#     def validate(self, data):
#         if 'user_inputs' not in data:
#             raise serializers.ValidationError(
#                 {'user_inputs': 'This field is required'})
#         user_inputs_validator(data['user_inputs'])
#         return data
#
#
# class InstituteStudentVerifyExamPageInputSerializer(serializers.Serializer):
#     exam_page_id = serializers.CharField()
#
#
# class PublicGetQuestionExamPageInputSerializer(serializers.Serializer):
#     group_index = serializers.IntegerField()
#     question_index = serializers.IntegerField()
#
#
# class PublicGetGroupExamPageInputSerializer(serializers.Serializer):
#     group_index = serializers.IntegerField()
#
#
# class InstituteStudentGetGroupExamPageInputSerializer(serializers.Serializer):
#     group_index = serializers.IntegerField()
#
#
# class PublicSetAnswerExamPageInputSerializer(serializers.Serializer):
#     user_inputs = serializers.JSONField(required=False)
#     go_to_next_question = serializers.BooleanField()
#
#     def validate(self, data):
#         if 'user_inputs' not in data:
#             raise serializers.ValidationError(
#                 {'user_inputs': 'This field is required'})
#         user_inputs_validator(data['user_inputs'])
#         return data
#
#
# class PublicAnswerFileExamPageInputSerializer(serializers.Serializer):
#     question_index = serializers.IntegerField(required=True)
#     group_index = serializers.IntegerField(required=True)
#     file = serializers.FileField(validators=[validators.answer_file_validator])
#
#
# class InstituteStudentAnswerFileExamPageInputSerializer(serializers.Serializer):
#     question_index = serializers.IntegerField(required=True)
#     group_index = serializers.IntegerField(required=True)
#     file = serializers.FileField(validators=[validators.answer_file_validator])
#
#
# class PublicAnswerFileDeleteExamPageInputSerializer(serializers.Serializer):
#     file_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#     question_index = serializers.IntegerField(required=True)
#     group_index = serializers.IntegerField(required=True)
#
#
# class InstituteStudentAnswerFileDeleteExamPageInputSerializer(serializers.Serializer):
#     file_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#     question_index = serializers.IntegerField(required=True)
#     group_index = serializers.IntegerField(required=True)
#
#
# class GetAnswerFileModelSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = AnswerFile
#         fields = ['id', 'question_index', 'group_index', 'file_type', 'file']
#
#
# class PauseExamInputSerializer(serializers.Serializer):
#     exam_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#     pause = serializers.BooleanField(required=True)
#
#
# class IncreaseTimeExamPageInputSerializer(serializers.Serializer):
#     exam_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#     start_date = serializers.DateTimeField(required=False)
#     end_date = serializers.DateTimeField(required=False)
#     duration = serializers.DurationField(required=False)
#
#
# class AttendedExamSerializer(serializers.ModelSerializer):
#     institute = SafeInstituteSerializerForExam()
#
#     class Meta:
#         model = Exam
#         fields = ['id', 'name', 'description', 'institute', 'public_id']
#
#
# class AttendedExamsListInputSerializer(serializers.Serializer):
#     skip = serializers.IntegerField(validators=[MinValueValidator(0)])
#     take = serializers.IntegerField(
#         validators=[MinValueValidator(1), MaxValueValidator(100)])
#     q = serializers.CharField(max_length=100, required=False, allow_null=True)
#
#
# class AttendedExamPageSerializer(serializers.ModelSerializer):
#     exam = AttendedExamSerializer()
#
#     class Meta:
#         model = ExamPage
#         fields = ['id', 'exam', 'state', 'final_score',
#                   'device_token', 'entrance_date', 'finished_at']
#
#
# class GetQuestionAnswerSheetFromScorePublishedPublicExamPageInputSerializer(serializers.Serializer):
#     public_id = serializers.CharField()
#     question_id = serializers.CharField()
#     group_index = serializers.IntegerField()
#     question_index = serializers.IntegerField()
#
#
# class GetQuestionAnswerSheetFromScorePublishedInstituteStudentExamPageInputSerializer(serializers.Serializer):
#     entrance_token = serializers.CharField()
#     question_id = serializers.CharField()
#     group_index = serializers.IntegerField()
#     question_index = serializers.IntegerField()
#
#
# class GetExamPageForExaminerInputSerializer(serializers.Serializer):
#     exam_page_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#
#
# class GetExamPageForExaminerSerializer(serializers.ModelSerializer):
#     user = PublicUserSerializer()
#     corrections = serializers.SerializerMethodField('corrections_generator')
#     answer_file = serializers.SerializerMethodField('answer_file_generator')
#     institute_student = InstituteStudentSerializerForExamStat()
#
#     class Meta:
#         model = ExamPage
#         fields = ['id', 'final_score', 'state', 'entrance_date', 'report_card', 'user', 'institute_student', 'finished_at', 'user_inputs',
#                   'generated_exam', 'corrections', 'answer_file']
#
#     def corrections_generator(self, exam_page):
#         corrections = Corrections.objects.filter(exam_page=exam_page)
#         return GetCorrectionsForStudentSerializer(corrections, many=True).data
#
#     def answer_file_generator(self, exam_page):
#         answer_files = AnswerFile.objects.filter(exam_page=exam_page)
#         return GetAnswerFileModelSerializer(answer_files, many=True).data
#
#
# class AddExamPageCorrectionInputSerializer(serializers.Serializer):
#     exam_page_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
#     group_index = serializers.IntegerField()
#     question_index = serializers.IntegerField()
#     score = serializers.FloatField()
#     comment_for_student = serializers.CharField(required=False)
#     comment_for_other_correctors = serializers.CharField(required=False)
#
#
# class PublishExamPageCorrectionInputSerializer(serializers.Serializer):
#     exam_page_id = serializers.CharField(
#         validators=[main_validators.uuid_validator])
