import uuid
import os

from cached_property import cached_property
from starlette.routing import Match

from .base import BaseProvider, context_field
from intranet.domenator.src.logic.utils.credential_sanitizer import CredentialSanitizer


class RequestProvider(BaseProvider):
    @property
    def http_request(self):
        return self.kwargs.get('request')

    @cached_property
    def matching_route(self):
        if self.http_request is None:
            return None
        for route in self.http_request.scope['app'].routes:
            if route.matches(self.http_request)[0] == Match.FULL:
                return route
        return None

    @context_field('http')
    def user(self):
        uid = ''
        if hasattr(self.http_request, 'user'):
            uid = getattr(self.http_request.user, 'uid', '')
        return {
            'uid': uid,
        }

    @context_field('http')
    def request(self):
        path = self.http_request.url.path
        qs = self.http_request.query_params
        uri = f'{path}?{qs}' if qs else path
        headers = CredentialSanitizer.get_headers_list_with_sanitized_credentials(self.http_request.headers)
        return {
            'method': self.http_request.method,
            'path': path,
            'uri': uri,
            'proto': f'HTTP/{self.http_request.scope["http_version"]}',
            'operation_id': getattr(self.matching_route, 'operation_id', ''),
            'headers': ' '.join([f'"{k}: {v}"' for k, v in headers]),
            'tags': getattr(self.matching_route, 'tags', ''),
            'route': getattr(self.matching_route, 'path', ''),
        }

    @context_field('http')
    def request_id(self):
        return str(uuid.uuid4())

    @context_field('http')
    def ycrid(self):
        new_ycrid = f'domenator-{uuid.uuid4().hex}-{os.environ.get("DEPLOY_POD_PERSISTENT_FQDN", "")}'
        return self.http_request.headers.get('X-Request-ID') or new_ycrid
