# -- encoding: utf-8 --

# Python
import hashlib
import re
import json
import traceback
import sys

from django.core.urlresolvers import reverse, resolve
from survey.utils import response_standard

# Django
from django.http import HttpResponse, JsonResponse
from django.conf import settings
from rest_framework.views import status

from .api import StudyTokenApi, ParticipantTokenApi

import logging
logger = logging.getLogger(__name__)


DEBUG = getattr(settings, "DEBUG", False)

STUDY_TOKEN_SKIP_VALIDATION = getattr(settings, "STUDY_TOKEN_SKIP_VALIDATION", False)
PARTICIPANT_TOKEN_SKIP_VALIDATION = getattr(settings, "PARTICIPANT_TOKEN_SKIP_VALIDATION", False)
SKIP_POST_CALLS_ONLY = getattr(settings, "SKIP_POST_CALLS_ONLY", False)


class ValidateStudyTokenMiddleware:
    def process_request(self, request):
        url_name = ""
        try:
            match = resolve(request.path)
            url_name = match.url_name
        except Exception as e:
            pass
        if "api" not in request.path:
            return
        for skip in STUDY_TOKEN_SKIP_VALIDATION:
            if skip == url_name:
                return
        if 'HTTP_X_STUDY_TOKEN' not in request.META:
            if DEBUG and 'X_STUDY_TOKEN' in request.GET:
                token = request.GET['X_STUDY_TOKEN']
                logger.debug("HTTP_X_STUDY_TOKEN' not in request.META request.GET[X_STUDY_TOKEN] token=" + str(token))
            else:
                return JsonResponse({"error": "Study token required"}, status=status.HTTP_400_BAD_REQUEST)
        else:
            token = request.META["HTTP_X_STUDY_TOKEN"]
            logger.debug("HTTP_X_STUDY_TOKEN in request.META  token=" + str(token))
        logger.debug("token=%s", str(token))
        study_token = StudyTokenApi()._get(token)
        if study_token == False:
            logger.error("Invalid Study token")
            return JsonResponse({"error": "Invalid Study token"},status=status.HTTP_400_BAD_REQUEST)

        logger.debug("StudyTokenApi()._get(token) study_token=" + str(study_token))
        request.study_token = study_token


class ValidateParticipantTokenMiddleware:
    def process_request(self, request):
        url_name = ""
        try:
            match = resolve(request.path)
            url_name = match.url_name
        except Exception as e:
            pass
        if "api" not in request.path:
            return
        for skip in PARTICIPANT_TOKEN_SKIP_VALIDATION:
            if skip == url_name:
                return
        if request.method == "POST":
            for skip in SKIP_POST_CALLS_ONLY:
                if skip == url_name:
                    return
        if not request.study_token:
            return JsonResponse({"error": "Study token required"},status=status.HTTP_400_BAD_REQUEST)
        if 'HTTP_X_PARTICIPANT_TOKEN' not in request.META:
            if DEBUG and 'X_PARTICIPANT_TOKEN' in request.GET:
                token = request.GET['X_PARTICIPANT_TOKEN']
                logger.debug("HTTP_X_PARTICIPANT_TOKEN' not in request.META request.GET['X_PARTICIPANT_TOKEN'] token=" + str(token))
            else:
                return JsonResponse({"error": "Participant token required"},status=status.HTTP_400_BAD_REQUEST)
        else:
            token = request.META['HTTP_X_PARTICIPANT_TOKEN']
            logger.debug("HTTP_X_PARTICIPANT_TOKEN' in request.META token=" + str(token))
        
        logger.debug("call ParticipantTokenApi()._get token=%s  request.study_token=%s:", str(token), str(request.study_token))
        participant_token = ParticipantTokenApi()._get( token, request.study_token)
        if participant_token == False:
            logger.error("Invalid Participant token:" + str(participant_token))
            return JsonResponse({"error": "Invalid Participant token"},status=status.HTTP_400_BAD_REQUEST)
        request.participant_token = participant_token

class ProcessExceptionMiddleware(object):
    def process_response(self, request, response):
        # srlg changed 200 to  or 201
        if (response.status_code != 200) and (response.status_code != 201):
            logger.debug("request:")
            logger.debug(request)
            logger.info('status_code: ' + str(response.status_code))
            logger.exception('ProcessExceptionMiddleware: ' + '\n'.join(traceback.format_exception(*sys.exc_info())))
        return response
