#include <util/digest/fnv.h>
#include <util/string/builder.h>

#include <library/cpp/getopt/last_getopt.h>
#include <mapreduce/yt/interface/client.h>

#include <wmconsole/version3/wmcutil/yt/yt_utils.h>

#include "partition.h"
#include "run_config.h"
#include "task_urls.h"
#include "tasks.h"
#include "util.h"

namespace NWebmaster {

namespace {
const char *FIELD_HOST = "Host";
const char *FIELD_PATH = "Path";
const char *FIELD_LAST_ACCESS = "LastAccess";
const char *FIELD_TITLE = "Title";
const char *FIELD_URL_STATUS = "UrlStatus";
}

void PackUrls(const NYT::TNode &row, TStringBuilder &data) {
    const TString &title = row[FIELD_TITLE].AsString();
    data << "2016-12-01" << "\t"
         << GetHostId(row[FIELD_HOST].AsString()) << "\t"
         << PrintTimestampField(row, FIELD_LAST_ACCESS) << "\t"
         << encode(row[FIELD_PATH].AsString()) << "\t"
         << encode(title) << "\t"
         << ToString(row[FIELD_URL_STATUS].AsUint64()) << "\n";
}

size_t HashPart(const NYT::TNode &row) {
    const TString &host = row[FIELD_HOST].AsString();
    return FnvHash<size_t>(GetHostId(host));
}

size_t HashLine(const NYT::TNode &row) {
    const TString &host = row[FIELD_HOST].AsString();
    const TString &path = row[FIELD_PATH].AsString();
    return FnvHash<size_t>(host + path);
}

void TMapUrls::Do(TReader *reader, TWriter *writer) {
    const TRunConfig &config = TRunConfig::CInstance();
    TStringBuilder data;
    for (; reader->IsValid(); reader->Next()) {
        if (NYTUtils::IsNodeNull(reader->GetRow()[FIELD_LAST_ACCESS])) {
            continue;
        }
        size_t partId = HashPart(reader->GetRow()) % config.TablesCount;
        size_t lineId = HashLine(reader->GetRow()) % config.LinesCount;
        PackUrls(reader->GetRow(), data);
        writer->AddRow(NYT::TNode()
                           (TReduceCompressPartition::F_PARTITION_ID, partId)
                           (TReduceCompressPartition::F_LINE_ID, lineId)
                           (TReduceCompressPartition::F_ROW_ID, reader->GetRowIndex())
                           (TReduceCompressPartition::F_DATA, data)
        );
        data.clear();
    }
}

} //namespace NWebmaster
