#include <library/cpp/string_utils/url/url.h>

#include <wmconsole/version3/wmcutil/hostid.h>
#include <wmconsole/version3/wmcutil/yt/yt_runner.h>
#include <wmconsole/version3/wmcutil/thread.h>

#include "config.h"
#include "monitor.h"
#include "user_settings.h"

namespace NWebmaster {

namespace {
const char *F_HOST                  = "Host";
const char *F_USER_SETTINGS         = "UserSettings";
const char *F_US_CHANNEL_EMAIL      = "channel_email";
const char *F_US_CHANNEL_SERVICE    = "channel_service";
const char *F_US_HOST_ID            = "host_id";
const char *F_US_NOTIFICATION_TYPE  = "notification_type";
}

struct TExtractUserSettingsMapper : public NYT::IMapper<NYT::TTableReader<NYT::TNode>, NYT::TTableWriter<NYT::TNode>> {
    Y_SAVELOAD_JOB(NotificationType)

    TExtractUserSettingsMapper() = default;

    TExtractUserSettingsMapper(TString notificationType)
            :NotificationType(notificationType)
    {
    }

public:
    void Do(TReader *input, TWriter *output) override {
        for (; input->IsValid(); input->Next()) {
            const NYT::TNode &row = input->GetRow();

            //const size_t userId = row[F_US_USER_ID].AsUint64();
            const TString hostId = row[F_US_HOST_ID].AsString();
            const TString notificationType = row[F_US_NOTIFICATION_TYPE].AsString();
            const bool channelService = row[F_US_CHANNEL_SERVICE].AsBool();
            const bool channelEmail = row[F_US_CHANNEL_EMAIL].AsBool();

            if (notificationType != NotificationType) {
                continue;
            }

            if (!channelService && !channelEmail) {
                continue;
            }

            output->AddRow(NYT::TNode()
                (F_HOST, TWebmasterHostId::FromHostId(hostId).ToHostName())
                (F_USER_SETTINGS, row)
            );
        }
    }
public:
    TString NotificationType;
};

REGISTER_MAPPER(TExtractUserSettingsMapper)

void PrepareUserSettings(NYT::IClientBasePtr clientSearch) {
    const auto &config = TConfig::CInstance();
    NYT::TTableSchema userSettingsSchema;
    userSettingsSchema.Strict(true);
    userSettingsSchema.AddColumn(NYT::TColumnSchema().Name(F_HOST).Type(NYT::VT_STRING));
    userSettingsSchema.AddColumn(NYT::TColumnSchema().Name(F_USER_SETTINGS).Type(NYT::VT_ANY));

    NYT::ITransactionPtr tx = clientSearch->StartTransaction();

    TOpRunner(tx)
        .InputNode(config.TABLE_SOURCE_USER_SETTINGS_CHANNELS)
        .OutputNode(NYT::TRichYPath(config.TABLE_DIGEST_SOURCE_USER_SETTINGS_CHANNELS).Schema(userSettingsSchema))
        .Map(new TExtractUserSettingsMapper("DIGEST"))
        .SortBy(F_HOST)
        .Sort(config.TABLE_DIGEST_SOURCE_USER_SETTINGS_CHANNELS);

    TOpRunner(tx)
            .InputNode(config.TABLE_SOURCE_USER_SETTINGS_CHANNELS)
            .OutputNode(NYT::TRichYPath(config.TABLE_DIGEST_LITE_SOURCE_USER_SETTINGS_CHANNELS).Schema(userSettingsSchema))
            .Map(new TExtractUserSettingsMapper("DIGEST_LITE"))
            .SortBy(F_HOST)
            .Sort(config.TABLE_DIGEST_LITE_SOURCE_USER_SETTINGS_CHANNELS);


    tx->Commit();
}

} //namespace NWebmaster
