#include <util/draft/date.h>
#include <util/generic/set.h>
#include <util/thread/pool.h>

#include <library/cpp/string_utils/url/url.h>
#include <robot/library/yt/static/command.h>
#include <robot/library/yt/static/table.h>
#include <yql/library/embedded/yql_embedded.h>
#include <kernel/urlnorm/normalize.h>

#undef LOG_DEBUG
#undef LOG_INFO
#undef LOG_ERROR

#include <wmconsole/version3/processors/siteservices/protos/sources.pb.h>
#include <wmconsole/version3/processors/siteservices/protos/services.pb.h>
#include <wmconsole/version3/processors/siteservices/conf/config.h>
#include <wmconsole/version3/wmcutil/yt/transfer_manager.h>
#include <wmconsole/version3/wmcutil/config_base.h>

#include <ctime>

#include "import_util.h"
#include "task_about_market_hosts.h"

namespace NWebmaster {
using namespace NJupiter;

int AboutMarketHosts(int, const char **) {
    const auto &cfg = TConfig::CInstance();
    NYT::IClientPtr client = NYT::CreateClient(cfg.MR_SERVER_HOST_MARKET);

    NYTUtils::CreatePath(client, cfg.TABLE_SERVICES_PREP_ROOT);

    TString tableTimestamp;
    TString maxSourceTimestamp = "-1";
    try {
        tableTimestamp = GetYtAttr(client, cfg.TABLE_SERVICES_PREP_MARKET, cfg.ATTR_UPDATE_SOURCE).AsString();
        maxSourceTimestamp = GetYtAttr(client, cfg.TABLE_SOURCE_MARKET, cfg.ATTR_CREATE_TIME).AsString();
    } catch (yexception &) {
    }

    if (tableTimestamp.equal(maxSourceTimestamp)){
        LOG_INFO("achievements, MarketHosts, Db already updated!");
        return 0;
    }

    LOG_INFO("achievements, MarketHosts, Start import table");
    TString marketTmp = cfg.TABLE_SERVICES_PREP_MARKET + "-tmp";
    NYT::ITransactionPtr tx = client->StartTransaction();
    auto reader = tx->CreateTableReader<NProto::TSrcMarket>(cfg.TABLE_SOURCE_MARKET);
    auto writer = tx->CreateTableWriter<NProto::TPrepMarket>(marketTmp);
    NProto::TPrepMarket prepMarket;

    for (; reader->IsValid(); reader->Next()) {
        const auto &row = reader->GetRow();
        TStringBuf host, path;
        SplitUrlToHostAndPath(row.GetDomain(), host, path);
        if (path.empty() || path == "/") {
            prepMarket.SetMascotOwner(GetOwner(row.GetDomain()));
            prepMarket.SetShopId(row.GetShopId());
            prepMarket.SetRating(round(row.GetRating()*10)/10);
            writer->AddRow(prepMarket);
        }
    }

    LOG_INFO("achievements, MarketHosts, Done copy table");

    writer->Finish();

    TSortCmd<NProto::TPrepMarket>(tx, TTable<NProto::TPrepMarket>(tx, marketTmp))
            .By({"MascotOwner"})
            .OperationWeight(cfg.OPERATION_WEIGHT)
            .Do();

    LOG_INFO("achievements, MarketHosts, Done sort table");

    auto readerTmp = tx->CreateTableReader<NProto::TPrepMarket>(marketTmp);
    writer = tx->CreateTableWriter<NProto::TPrepMarket>(cfg.TABLE_SERVICES_PREP_MARKET);
    TString prevOwner = "";
    for (; readerTmp->IsValid(); readerTmp->Next()) {
        const auto &row = readerTmp->GetRow();
        if (!prevOwner.equal(row.GetMascotOwner())) {
            TString normalized;
            if (NUrlNorm::NormalizeUrl(row.GetMascotOwner(), normalized)) {
                prepMarket.SetMascotOwner(GetOwner(normalized));
                prepMarket.SetShopId(row.GetShopId());
                prepMarket.SetRating(row.GetRating());
                writer->AddRow(prepMarket);
            }
        }
        prevOwner = row.GetMascotOwner();
    }
    writer->Finish();

    TSortCmd<NProto::TPrepMarket>(tx, TTable<NProto::TPrepMarket>(tx, cfg.TABLE_SERVICES_PREP_MARKET))
            .By({"MascotOwner"})
            .OperationWeight(cfg.OPERATION_WEIGHT)
            .Do();


    SetYtAttr(tx, cfg.TABLE_SERVICES_PREP_MARKET, cfg.ATTR_UPDATE_SOURCE, maxSourceTimestamp);

    tx->Commit();

    TTransferManager tManager(TConfigBase::GetYTToken());
    tManager.PostTaskAndWait(cfg.MR_SERVER_HOST_MARKET, cfg.TABLE_SERVICES_PREP_MARKET, cfg.MR_SERVER_HOST, cfg.TABLE_SERVICES_PREP_MARKET);

    LOG_INFO("achievements, MarketHosts, Import done");
    return 0;
}
} //namespace NWebmaster
