from flask import request
import jwt
import bugsnag
from dependency_injector.wiring import Provide, inject

from auth_middleware import AuthMiddleware
from response_templates.response_builders import solar_auth_failure_response
from emi_service import EMIService
from emi_containers import EMIContainer


class NoTouchMiddleware:

    @classmethod
    def main(cls, func):
        @inject
        def wrapper_v1(emi_service: EMIService = Provide[EMIContainer.emi_service], *args, **kwargs):
            try:
                request_data = request.get_json(force=True)
                request_application_id = request_data.get('application_id')
                request_mobile_number = request_data.get('mobile_number', None)
                if request_mobile_number and not request_application_id:
                    request_application_id = emi_service.get_application_details_by_mobile(request_mobile_number)
                if 'HTTP_AUTHORIZATION' in request.environ:
                    token = request.environ['HTTP_AUTHORIZATION'].replace('Bearer ', '')
                    token_data = cls.jwt_decode(token)
                    if token_data.get('token_type') == 'access':
                        user_id = token_data.get('id')
                        applicant_id = token_data.get('applicant_id')
                        application_id = emi_service.get_consumer_application_id(user_id)
                        if not application_id:
                            application_id = emi_service.get_consumer_application_id_by_applicant_id(applicant_id)
                        if (not user_id and not applicant_id) or not application_id:
                            return solar_auth_failure_response(code='SF10401', )
                        if application_id != int(request_application_id):
                            return solar_auth_failure_response(code='SF10401', )
                    elif token_data.get('token_type') == 'temporary':
                        mobile_number = token_data.get('mobile_number')
                        if not mobile_number:
                            return solar_auth_failure_response(code='SF10401', )
                request_valid = AuthMiddleware('env').main()
                if request_valid:
                    return func(*args, **kwargs)
                return solar_auth_failure_response(code='SF10401', )
            except Exception as ex:
                bugsnag.notify(ex)
                return solar_auth_failure_response(code='SF10401', )
        return wrapper_v1

    @staticmethod
    def jwt_decode(token, ):
        payload = jwt.decode(token, options={"verify_signature": False})
        return payload

    @staticmethod
    def main_v1(func, *args, **kwargs):
        """
        By passing the authentication for release on master for solar replacement

        Parameters:
        - func (viewpoint): Endpoint route/viewpoint
        - args: any arguments if present
        - kwargs: any keyword arguments if present
        """
        def wrapper():
            return func(*args, **kwargs)
        return wrapper
