-- затюненая версия

-- тестовая переменная, чтобы генерить таблицу не на сегодня
$today = CurrentUtcDate() - Interval("P0D");

-- yql присылал варнингы на мои outstanding-решения, поэтому вот
PRAGMA AnsiInForEmptyOrNullableItemsCollections;

-- по каждому URL_start
$min_traffic = 3;
$min_script_traffic = 3;
$min_script_prcnt = 0.15;

-- необходимый минимум старт_урлов, чтобы поднять small проблему
$small_min_script_cnt = 10;

-- необходимый скриптовый трафик на старт_урле, чтобы поднять big проблему
$big_min_script_traffic = 12;


-- Это суперпопулярные скрипты, которые заведомо подгружаются за счёт расширений браузера - их игнорим
$script_whitelist_ignore = ["kaspersky-labs.com", "chrome-extension"];
-- Или скрипты, которые +- можно использовать, наказывать за это не надо, но мы внимательно следим
$script_whitelist_monitor = ["pay.google.com"];

use hahn;
-- Домены, принадлежащие Яндексу
$ya_domains = SELECT domain FROM `home/scarif/external_scripts/lib_tables/ya_domains`;
-- Домены, принадлежащие Яндексу, но бескуковые (игнорировать в тикетах)
$ya_non_cookie_domains = SELECT domain FROM `home/scarif/external_scripts/lib_tables/ya_non_cookie_domains`;
-- Рекламные домены, не принадлежащие Яндексу
$ad_domains = SELECT domain FROM `home/scarif/external_scripts/lib_tables/ad_domains`;


-- функция, с помощью которой я подгружу в $data интервал из 7 таблиц
$interval = ($table_name) -> {
    return Interval("P2D") <= $today - Cast($table_name as date) AND
           Interval("P8D") >= $today - Cast($table_name as date);
};
-- Собираем с логфеллера все нужные данные 
$data =
    SELECT
        StartURL as URL_parameter,
        -- Костыль, убирающий опции и комментарии у URLов
        Url::GetHost(StartURL) || Url::GetPath(StartURL) as URL_start,
        CASE
            -- Внешний рекламный трафик ~ AdvEngineID не-null и при этом не соответствует Яндексу
            -- https://wiki.yandex-team.ru/jandexmetrika/data/metrikatables/visits/advengineid/
            WHEN AdvEngineID not in (1,12,71,73,91)
            THEN 1
            ELSE 0
        END as is_traffic_ad,
        ListUniq(
            ListMap(
                -- Превращает Yson в список строк
                Yson::ConvertToStringList(ParsedParams_Key2),
                -- Превращает ссылку в смысловой домен
                Url::GetOwner
            )
        ) as script_URLs,
        Sign,
    FROM FILTER(`home/logfeller/logs/visit-v2-log/1d`, $interval)
    WHERE
        CounterID = 51533966 AND
        StartURL = EndURL AND
        Url::GetSignificantDomain(StartURL) in $ya_domains AND
        Url::GetSignificantDomain(StartURL) not in $ya_non_cookie_domains AND
        -- Не забываем, что теоретически в ParsedParams_Key1 бывает 'cds'
        "scripts" in Yson::ConvertToStringList(ParsedParams_Key1)
;

-- -- запись в кеш
-- INSERT INTO `home/scarif/external_scripts/experiments/test_tables/data` WITH TRUNCATE 
-- SELECT * FROM $data;

-- -- типа кеш
-- $data = SELECT * FROM `home/scarif/external_scripts/experiments/test_tables/data`;

-- Сохраним таблицу URL_start -> traffic, обогатим ею $data
$URL_start_to_traffic =
SELECT
    URL_start,
    sum(Sign*is_traffic_ad) as traffic_ad,
    sum(Sign*(1-is_traffic_ad)) as traffic_non_ad,
    sum(Sign) as traffic,
FROM $data
GROUP BY URL_start
;

-- Обогощаем $data трафиком и рекламным трафиком
-- по каждому URL'у пишем рекламный ли он
-- отсекаем URL'ы с маленьким трафиком
$data =
SELECT
    a.Sign as Sign,
    a.URL_start as URL_start,
    a.is_traffic_ad as is_traffic_ad,
    b.traffic_ad as traffic_ad,
    b.traffic_non_ad as traffic_non_ad,
    b.traffic as traffic,
    a.URL_parameter as URL_parameter,
    a.script_URLs as script_URLs,
    CASE
        WHEN cast(traffic_ad as float)/traffic >= 0.7
        THEN True
        ELSE False
    END as is_URL_ad,
FROM
    $data as a
JOIN
    $URL_start_to_traffic as b
ON
    a.URL_start = b.URL_start
WHERE
    traffic >= $min_traffic
;

-- Раскроем $data поскриптово — с каждым скриптом в URL_example будем работать отдельно
-- По каждому скрипту скажем рекламный ли он
-- Отсечём
-- -- мусор в виде 'cds':'g' и 'cds':'s'
-- -- скрипты Касперского из $script_whitelist_ignore
-- -- Яндексовые скрипты
$data_scripts =
SELECT
    Sign,
    script_URL,
    URL_start,
    URL_parameter as URL_example,
    traffic,
    traffic_non_ad,
    traffic_ad,
    is_URL_ad,
    is_traffic_ad,
    CASE
        WHEN Url::GetOwner(script_URL) in $ad_domains
        THEN True
        ELSE False
    END as is_script_ad
FROM
    $data
FLATTEN BY script_URLs as script_URL
WHERE
    len(script_URL) > 2 AND
    Url::GetSignificantDomain(script_URL) not in $ya_domains AND
    script_URL not in $script_whitelist_ignore
;

-- Ещё отсечём рекламные скрипты на рекламных URL'ах
$data_scripts =
SELECT
    *
FROM
    $data_scripts
WHERE
    NOT(
        is_URL_ad
        AND is_script_ad
    )
;

-- сопоставим каждому скрипту его трафик в рамках URL_start
$URL_start_script_URL_to_traffic =
SELECT
    sum(Sign) as script_traffic,
    sum(Sign*is_traffic_ad) as script_traffic_ad,
    sum(Sign*(1-is_traffic_ad)) as script_traffic_non_ad,
    script_URL,
    URL_start
FROM $data_scripts
GROUP BY URL_start, script_URL
;

-- обогатим $data_scripts данными о трафике скриптов
-- по каждому $URL_start говорю рекламный ли он
-- отсечём строчки с маленькой относительной/абсолютной доле скриптового трафика
$data_scripts = 
SELECT
    *
FROM
    $data_scripts as a
JOIN
    $URL_start_script_URL_to_traffic as b
ON
    a.script_URL = b.script_URL AND a.URL_start = b.URL_start
WHERE
    CASE
        WHEN is_script_ad
        THEN
            cast(script_traffic_non_ad as float) / traffic_non_ad >= $min_script_prcnt
            AND script_traffic_non_ad >= $min_script_traffic
        ELSE
            cast(script_traffic as float) / traffic >= $min_script_prcnt
            AND script_traffic >= $min_script_traffic
    END

;

$data_scripts_start_aggregate =
SELECT
    URL_start,

    CASE
        WHEN is_URL_ad
        THEN some(URL_example)
        ELSE null
    END as example_ad,
    CASE
        WHEN is_URL_ad = False
        THEN some(URL_example)
        ELSE null
    END as example_non_ad,

    script_URL,
    is_script_ad,
    CASE
        WHEN Url::GetOwner(script_URL) in $script_whitelist_monitor
        THEN True
        ELSE False
    END as is_script_whitelist_monitor,

    traffic,
    traffic_ad,
    traffic_non_ad,

    script_traffic,
    script_traffic_ad,
    script_traffic_non_ad
FROM $data_scripts
GROUP BY
    URL_start,
    
    is_URL_ad,

    script_URL,
    is_script_ad,

    traffic,
    traffic_ad,
    traffic_non_ad,

    script_traffic,
    script_traffic_ad,
    script_traffic_non_ad
;

-- Таблица, с помощью которой мы сопоставим домену ABC-сервис
$abc_domains =
    SELECT AGGREGATE_LIST((regex, abc, common_URL, description, whitelist))
    FROM `home/scarif/external_scripts/lib_tables/abc_domains`
;

-- Сама функция
$url_to_abc = Python3::url_to_abc(
    Callable<
        (
            String?,
            List<
                Tuple<
                    String?,
                    String?,
                    String?,
                    String?,
                    Bool?
                >
            >?
        ) -> 
        Struct<
            abc:String?,
            common_URL:String?,
            description:String?,
            whitelist:Bool?
        >
    >, @@
import re

def url_to_abc(url, abc_domains):
    for index in range(len(abc_domains)):
        regex, abc, common_URL, description, whitelist = abc_domains[index]
        if re.search(regex, url):
            return {'abc': abc,
                    'common_URL': common_URL,
                    'description': description,
                    'whitelist': whitelist}
    else:
        return {'abc': None,
                'common_URL': None,
                'description': None,
                'whitelist': None}

url_to_abc._yql_lazy_input = False
@@);

-- 1/3 Достанем домены, из которых уже отсечены только с Яндексовыми скриптами или с малым трафиком
$URL_start_to_ABC =
SELECT
    URL_start
FROM $data_scripts_start_aggregate
GROUP BY URL_start
;

-- 2/3 Сопоставим каждому урлу ABC
$URL_start_to_ABC = 
    SELECT
        URL_start,
        $url_to_abc(
            table.URL_start,
            $abc_domains
        ) as abc_column
    FROM $URL_start_to_ABC as table
;

-- 3/3 Распакуем abc_column по колонкам
$URL_start_to_ABC = 
    SELECT
        URL_start,
        abc_column.abc as abc,
        abc_column.common_URL as common_URL,
        abc_column.whitelist as abc_whitelist,
    FROM $URL_start_to_ABC as table
;

-- -- запись в кеш
-- INSERT INTO `home/scarif/external_scripts/experiments/test_tables/URL_start_to_ABC` WITH TRUNCATE 
-- SELECT * FROM $URL_start_to_ABC;

-- -- типа кеш
-- $URL_start_to_ABC = SELECT * FROM `home/scarif/external_scripts/experiments/test_tables/URL_start_to_ABC`;

$data_scripts_start_aggregate =
SELECT *
FROM
    $data_scripts_start_aggregate as a
JOIN
    $URL_start_to_ABC as b
ON a.URL_start = b.URL_start
;

$unknown_url =
SELECT
    CASE
        WHEN example_non_ad is not null
        THEN example_non_ad
        ELSE example_ad
    END as URL_example,
FROM
    $data_scripts_start_aggregate
WHERE
    abc is null
;


$common_URL_script_URL_to_cnt =
SELECT
    common_URL,
    script_URL,
    count(*) as common_URL_script_URL_cnt
FROM
    $data_scripts_start_aggregate
GROUP BY
    common_URL, script_URL
;

$data_scripts_start_aggregate =
SELECT *
FROM
    $data_scripts_start_aggregate as a
JOIN
    $common_URL_script_URL_to_cnt as b
ON
    a.common_URL = b.common_URL AND a.script_URL = b.script_URL
;

$small_problems =
SELECT
    abc,
    abc_whitelist,
    common_URL,
    script_URL,
    is_script_ad,
    is_script_whitelist_monitor,
    AGGREGATE_LIST(
        <|
        'example_ad': example_ad,
        'example_non_ad': example_non_ad,

        'traffic': traffic,
        'traffic_ad': traffic_ad,
        'traffic_non_ad': traffic_non_ad,

        'script_traffic': script_traffic,
        'script_traffic_ad': script_traffic_ad,
        'script_traffic_non_ad': script_traffic_non_ad,
        |>
    ) as examples,
    'small' as problem_type
FROM
    $data_scripts_start_aggregate
WHERE
    common_URL_script_URL_cnt >= $small_min_script_cnt
GROUP BY
    common_URL, script_URL, is_script_ad, is_script_whitelist_monitor, abc, abc_whitelist
;

$big_problems =
SELECT
    abc,
    abc_whitelist,
    common_URL,
    script_URL,
    is_script_ad,
    is_script_whitelist_monitor,
    AGGREGATE_LIST(
        <|
        'example_ad': example_ad,
        'example_non_ad': example_non_ad,

        'traffic': traffic,
        'traffic_ad': traffic_ad,
        'traffic_non_ad': traffic_non_ad,

        'script_traffic': script_traffic,
        'script_traffic_ad': script_traffic_ad,
        'script_traffic_non_ad': script_traffic_non_ad,
        |>
    ) as examples,
    'big' as problem_type
FROM
    $data_scripts_start_aggregate
WHERE
    common_URL_script_URL_cnt < $small_min_script_cnt AND
    CASE
        WHEN is_script_ad
        THEN script_traffic_non_ad >= $big_min_script_traffic
        ELSE script_traffic >= $big_min_script_traffic
    END
GROUP BY
    common_URL, script_URL, is_script_ad, is_script_whitelist_monitor, abc, abc_whitelist
;

$problems =
SELECT * FROM $small_problems
UNION ALL
SELECT * FROM $big_problems;

$problems_whitelist_monitor =
SELECT
    common_URL,
    abc,
    abc_whitelist,
    Yson::From(
        AGGREGATE_LIST(
            <|
                'script_URL': script_URL,
                'is_script_ad': is_script_ad,
                'problem_type': problem_type,
                'examples': examples
            |>
        )
    ) as scripts
FROM
    $problems
WHERE is_script_whitelist_monitor
GROUP BY
    common_URL,
    abc,
    abc_whitelist
;

$problems =
SELECT
    common_URL,
    abc,
    abc_whitelist,
    Yson::From(
        AGGREGATE_LIST(
            <|
                'script_URL': script_URL,
                'is_script_ad': is_script_ad,
                'problem_type': problem_type,
                'examples': examples
            |>
        )
    ) as scripts
FROM
    $problems
WHERE not is_script_whitelist_monitor
GROUP BY
    common_URL,
    abc,
    abc_whitelist
;


$unknown_abc_out_path =
    "home/scarif/external_scripts/unknown_abc_tables/" || 
    cast($today as string)
;
PRAGMA yt.ExpirationInterval='90d';
INSERT INTO $unknown_abc_out_path WITH TRUNCATE
SELECT *
FROM $unknown_url;


$whitelist_monitor_out_path =
    "home/scarif/external_scripts/whitelist_monitor_tables/" || 
    -- "home/scarif/external_scripts/experiments/test_tables/ticket_tables/test_small_2_" || 
    cast($today as string)
;
PRAGMA yt.ExpirationInterval='90d';
INSERT INTO $whitelist_monitor_out_path WITH TRUNCATE
SELECT *
FROM $problems_whitelist_monitor;


$ticket_out_path =
    "home/scarif/external_scripts/ticket_tables/" || 
    -- "home/scarif/external_scripts/experiments/test_tables/ticket_tables/test_small_2_" || 
    cast($today as string)
;
PRAGMA yt.ExpirationInterval='90d';
INSERT INTO $ticket_out_path WITH TRUNCATE
SELECT *
FROM $problems;


SELECT "//" || $ticket_out_path as table;