import logging
from abc import ABC
from ssl import TLSVersion

import httpx
from djstarter.clients import Http2Client

from . import utils
from .models import Fingerprint, TLSFingerprint

logger = logging.getLogger(__name__)


class DesktopClient(ABC, Http2Client):
    def __init__(self, fingerprint=None, proxy=None, *args, **kwargs):
        self.fingerprint = fingerprint or self.temp_fingerprint()
        self.proxy = proxy
        self.tls_fingerprint = self.fingerprint.tls_fingerprint or self.generate_tls_fingerprint()
        self.user_agent = self.fingerprint.user_agent
        super().__init__(
            proxies=self.proxies,
            verify=self.new_ssl_context(),
            *args,
            **kwargs
        )

    def send(self, *args, **kwargs):
        self.headers.pop('Accept-Encoding', None)
        self.headers.pop('Connection', None)
        return super().send(*args, **kwargs)

    def new_ssl_context(self):
        context = httpx.create_ssl_context(http2=True)
        context.minimum_version = TLSVersion.TLSv1_2
        context.set_ciphers(self.tls_fingerprint.ciphers)
        context.options = self.tls_fingerprint.extensions

        return context

    @property
    def proxies(self):
        if self.proxy:
            return {
                'http://': self.proxy.http_url,
                'https://': self.proxy.http_url
            }
        return dict()

    @staticmethod
    def temp_fingerprint():
        return Fingerprint.objects.get_random_desktop_fingerprint()

    def generate_tls_fingerprint(self):
        tls_fingerprint = TLSFingerprint.objects.create(browser=self.fingerprint.browser)
        self.fingerprint.tls_fingerprint = tls_fingerprint
        self.fingerprint.save()
        return tls_fingerprint


class DesktopChromeClient(DesktopClient):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.ua_parser = utils.UserAgentParser(self.user_agent)

    def init_headers(self):
        return {
            'user-agent': self.user_agent,
        }

    @property
    def sec_ch_ua(self):
        version = self.ua_parser.browser_major_version
        return f'" Not;A Brand";v="99", "Google Chrome";v="{version}", "Chromium";v="{version}"'

    @property
    def sec_ch_ua_mobile(self):
        return '?0'

    @property
    def sec_ch_ua_platform(self):
        platform = self.ua_parser.os
        return f'"{platform}"'


class DesktopFirefoxClient(DesktopClient):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def init_headers(self):
        return {
            'User-Agent': self.user_agent,
        }
