#pragma once

#include <util/generic/set.h>

#include <mapreduce/yt/interface/client.h>

#include <wmconsole/version3/protos/queries2.pb.h>
#include <wmconsole/version3/wmcutil/regex.h>

#include "config.h"
#include "week_config.h"

namespace NWebmaster {

struct TCounter {
    void Add(const proto::queries2::QueryMessage &msg) {
        for (int i = 0; i < msg.reports_by_region_size(); i++) {
            Add(msg.reports_by_region(i));
        }
    }

    void Add(const proto::queries2::QueryRegionInfo &regionMsg) {
        for (int p = 0; p < regionMsg.position_info_size(); p++) {
            const auto &position = regionMsg.position_info(p);
            Shows += position.shows_count();
            Clicks += position.clicks_count();
            WeightedPosition += static_cast<double>(position.shows_count() * position.position());
        }
    }
    void Add(long shows, long clicks, double position) {
        Shows += shows;
        Clicks += clicks;
        WeightedPosition += shows * position;
    }

    double GetPosition() const {
        return WeightedPosition / static_cast<double>(Shows);
    }

public:
    inline static long ShowsGetter(const TCounter &obj) {
        return obj.Shows;
    }

    inline static long ClicksGetter(const TCounter &obj) {
        return obj.Clicks;
    }

    inline static double PositionGetter(const TCounter &obj) {
        return obj.GetPosition();
    }

public:
    long Clicks = 0;
    long Shows = 0;
    double WeightedPosition = 0;
};

template<class T>
struct TSample {
    TSample() = default;
    TSample(T oldValue, T newValue)
        : OldValue(oldValue)
        , NewValue(newValue)
    {
    }

    inline T GetDiff() const {
        return NewValue - OldValue;
    }

    inline double GetDiffPercent() const {
        if (OldValue == 0) {
            return 0.0;
        }

        return (static_cast<double>(NewValue - OldValue) / static_cast<double>(OldValue)) * 100;
    }

public:
    T OldValue = 0;
    T NewValue = 0;
    TString Object;
};

TString GetAllFavoritesQueriesTableName(const TDigestWeekConfig &weekConfig);
TString GetAllQueriesTableName(const TDigestWeekConfig &weekConfig);
TString GetGroupsQueriesTableName(const TDigestWeekConfig &weekConfig);
TString GetPopularUrlsTableName(const TDigestWeekConfig &weekConfig);
TString GetSplitFavoritesQueriesTableName(const TDigestWeekConfig &weekConfig);
TString GetTopsQueriesTableName(const TDigestWeekConfig &weekConfig);

void PrepareAllQueriesSource(NYT::IClientBasePtr clientQueries, const THashSet<TString> &webmasterHosts, const TDigestWeekConfig &weekConfig);
void PrepareFavoritesQueriesSource(NYT::IClientBasePtr clientQueries, const TDigestWeekConfig &weekConfig);
void PrepareGroupsQueriesSource(NYT::IClientBasePtr clientQueries, const TDigestWeekConfig &weekConfig);
void PrepareGroupsSettingsSource(NYT::IClientBasePtr clientQueriesTx);
void PreparePopularUrlsSource(NYT::IClientBasePtr clientQueries, const THashSet<TString> &webmasterHosts, const TDigestWeekConfig &weekConfig);
void PrepareTopsQueriesSource(NYT::IClientBasePtr clientQueries, const TDigestWeekConfig &weekConfig);

} //namespace NWebmaster
