import logging
from collections import defaultdict
from urllib.parse import parse_qs, unquote, urlparse, urlencode, urlunparse

logger = logging.getLogger()


def _get_audit_pixel_param(params, param):
    if param not in params:
        logger.warning(
            f"Expected audit pixel parameter '{param}' hasn't been provided."
        )
        return None
    return params[param]


def _weborama_transform_audit_pixel(params):
    platform_id = 4
    si = _get_audit_pixel_param(params, "account")
    te = _get_audit_pixel_param(params, "tte")
    aap = _get_audit_pixel_param(params, "app")
    if None in (si, te, aap):
        return {}
    base_url = (
        f"https://verify.yandex.ru/verify?platformid={platform_id}"
        f"&a.si={si}&a.te={te}&a.aap={aap}&maid=[rdid]"
    )
    return {
        "audit-pixel-click-templated": base_url + "&a.A=cl",
        "audit-pixel-load-templated": base_url + "&a.A=ev&a.evn=load",
        "audit-pixel-im-templated": base_url + "&a.A=im",
        "audit-pixel-mrc50-templated": base_url + "&a.A=ev&a.evn=MRCViewable",
        "audit-pixel-mrc100-templated": base_url + "&a.A=ev&a.evn=MRC100Viewable",
    }


def _transform_templated_url_audit_pixel(*domain_names):
    def transform(params):
        url = _get_audit_pixel_param(params, "url")
        url_parts = urlparse(url)
        if (
            url is None
            or url_parts.netloc not in domain_names
            or url_parts.scheme not in ("http", "https")
        ):
            logger.warning(
                f"Invalid url for templated audit pixel: {url}, expecting 'http(s)://({','.join(domain_names)})/*'"
            )
            return {}
        return {"audit-pixel-im-templated": url}

    return transform


_dcm_transform_audit_pixel = _transform_templated_url_audit_pixel("ad.doubleclick.net")
_dcm_transform_audit_pixel_production = _dcm_transform_audit_pixel


def _dcm_transform_audit_pixel_testing(params):
    fields = _dcm_transform_audit_pixel(params)
    url = fields.get("audit-pixel-im-templated")
    if url is None or "[rdid]" in url:
        return fields

    url_parts = urlparse(url)
    qparams = parse_qs(url_parts.params, keep_blank_values=True, separator=";")
    qparams["dc_rdid"] = ["[uadid]"]
    qparams["dc_lat"] = ["[lat]"]
    url_parts = list(url_parts)
    url_parts[3] = unquote(urlencode(qparams, doseq=True)).replace("&", ";")
    return {
        "audit-pixel-im-templated"
        if "[timestamp]" in url
        else "audit-pixel-im": urlunparse(url_parts)
    }


_sizmek_transform_audit_pixel = _transform_templated_url_audit_pixel(
    "bs.serving-sys.com", "bs.serving-sys.ru"
)

TRANSFORM_AUDIT_PIXEL_ENGINES = {
    "weborama": {
        "production": _weborama_transform_audit_pixel,
        "testing": _weborama_transform_audit_pixel,
    },
    "dcm": {
        "production": _dcm_transform_audit_pixel_production,
        "testing": _dcm_transform_audit_pixel_testing,
    },
    "sizmek": {
        "production": _sizmek_transform_audit_pixel,
        "testing": _sizmek_transform_audit_pixel,
    },
}


def transform_audit_pixel(verification_data, ctype: str):
    tag_fields = defaultdict(list)
    for verification_datum in verification_data:
        platform = verification_datum.get("platform", "")
        if platform not in TRANSFORM_AUDIT_PIXEL_ENGINES:
            logger.warning(f"Unknown audit pixel platform '{platform}'.")
            continue

        feilds = TRANSFORM_AUDIT_PIXEL_ENGINES[platform][ctype](
            verification_datum.get("params", {})
        )

        for key, value in feilds.items():
            tag_fields[key].append(value)

    return tag_fields
