import json
import time
import requests
from django.test import TestCase
from authenticate.tests_helper import AuthenticateTestHelper
from collaborators.tests_helper import CollaboratorTestHelper
from doc_parser.tests_helper import DocParserTestHelper
from exam.tests_helper import ExamTestHelper
from institute.tests_helper import InstituteTestHelper
from payment.tests_helper import PaymentTestHelper
from plan.tests_helper import PlanTestHelper
from promotion.tests_helper import PromotionTestHelper
from public_resources.tests_helper import PublicResourceTestHelper
from question_bank.tests_helper import QuestionBankTestHelper
from question.tests_helper import QuestionTestHelper
from quiz.tests_helper import QuizTestHelper

messages = set()


class MyTestCase(TestCase):
    staging = False
    default_test_token = ""

    valid_names = ["valid name", "valid12", "valid name _ 123", " valid_name2", "valid_name3 ", "value - name",
                   "valid name (name 2)", "valid,name"]

    invalid_names = ["invalid/name", "invalid~name", "invalid%name", "invalid\\n name", "invalid~name",
                     "invalid\\\\name", "invalid+name", "invalid*name", "ab", "a%", "a*", ""]

    # this test_token expire on April 2031
    test_token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE5MzQ4MTEwMzgsImlzcyI6IlF1aXoiLCJ1c2VyX2lkIjoiNGRmNzEwZDYtZDU0My00MjEyLThhZTQtYWIwOGJkZDQ3NGIwIn0.tvOLkM-eGyHKA8zT4VZMr7uQwzONa45nut6bprOdidM'
    expired_token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE5MzQ4MTEwMzgsImlzcyI6IlF1aXoiLCJ1c2VyX2lkIjoiNGRmNzEwZDYtZDU0My00MjEyLThhZTQtYWIwOGJkZDQ3NGIwIn0.tvOLkM-eGyHKA8zT4VZMr7uQwzONa45nut6bprOdidH'

    non_existence_uuid = '123e4567-e89b-12d3-a456-426614174000'

    str10 = "abcdefghij"
    str20 = "abcdefghij1234567890"
    str100 = str20*5
    str1000 = str100*12

    def setUpHelpers(self):
        self.authenticateHelper = AuthenticateTestHelper(self)
        self.instituteHelper = InstituteTestHelper(self)
        self.collaboratorHelper = CollaboratorTestHelper(self)
        self.questionbankHelper = QuestionBankTestHelper(self)
        self.questionHelper = QuestionTestHelper(self)
        self.publicResourceHelper = PublicResourceTestHelper(self)
        self.examHelper = ExamTestHelper(self)
        self.quizHelper = QuizTestHelper(self)
        self.paymentHelper = PaymentTestHelper(self)
        self.DocParserHelper = DocParserTestHelper(self)
        self.PromotionHelper = PromotionTestHelper(self)
        self.planHelper = PlanTestHelper(self)

    def setBaseUser(self):
        self.authenticateHelper = AuthenticateTestHelper(self)
        (self.user, self.token) = self.authenticateHelper.new_user_with_email()
        self.setToken(self.token)

    def setToken(self, token):
        self.default_test_token = token

    def error_dumper(self, url, request, response):
        error_message = url + " "
        try:
            error_message += json.dumps(request)
        except TypeError:
            pass

        error_message += " "

        try:
            # print(response)
            error_message += json.dumps(response.data)
        except Exception as e:
            # print(str(e))
            # print(response.data)
            try:
                # print(response)
                error_message += str(response.data)
            except Exception as e:
                # print(str(e))
                # print(response.data)
                try:
                    # print(response)
                    error_message += str(response)
                except Exception as e:
                    # print(str(e))
                    # print(response.data)
                    pass
        return error_message

    def get(self, url, request=None):
        if request is None:
            request = {}

        response = self.client.get(url, request)
        response_data = str(response.content)
        status_code = response.status_code

        return response_data, status_code, self.error_dumper(url, request, response)

    def post_without_token(self, url, request=None, application_json=None):
        return self.post_with_token(url, request=request, test_token="", application_json=application_json)

    def post_with_token(self, url, request=None, test_token=None, application_json=None):
        if request is None:
            request = {}

        if test_token is None:
            test_token = self.default_test_token

        if application_json is None:
            application_json = False

        if self.staging:
            url = "https://cb1aml6r9b.execute-api.ap-south-1.amazonaws.com/staging" + url
            request.update({'token': test_token})
            response = requests.post(url, request)
            response_data = response.json()
            status_code = response.status_code
        else:
            request.update({'token': test_token})
            if application_json:
                response = self.client.post(
                    url, request, content_type="application/json")
            else:
                response = self.client.post(url, request)
            status_code = response.status_code
            try:
                response_data = response.data
            except Exception as e:
                print(status_code)
                try:
                    print(response.body)
                except:
                    pass
                try:
                    print(response.content)
                except:
                    pass
                raise e

            if "message" in response_data:
                length_before = len(messages)
                messages.add(response_data["message"] + "\n")
                length_after = len(messages)
                if length_before != length_after:
                    with open('found_messages.txt', 'w') as file:
                        file.writelines(messages)

        return response_data, status_code, self.error_dumper(url, request, response)

    def post_time_tester(self, url, request=None, test_token=None, application_json=None, count=100):
        start = time.time()
        for i in range(count):
            self.post_with_token(url(i), request(i) if request else None, test_token(i) if test_token else None,
                                 application_json(i) if application_json else None)

        return (time.time() - start) * 1000 / count
