#include "frame.h"
#include "signals.h"

#include <library/cpp/unistat/unistat.h>
#include <search/unistat_logger/resources.h>

#include <util/datetime/base.h>
#include <util/generic/size_literals.h>

namespace {
    double ToMilliseconds(ui64 microseconds) {
        return microseconds * 0.001;
    }

    double ToKilobytes(ui64 length) {
        return static_cast<double>(length) / 1_KB;
    }
}

void TSaasProxyUnistatFrame::OnSubSourceInit(const TString& subsource) {
    TUnistat::Instance().PushSignalUnsafe("search-CTYPE-" + ServiceName + "-init_subsource_" + subsource, 1);
}

void TSaasProxyUnistatFrame::OnSubSourceError(const TString& subsource) {
    TUnistat::Instance().PushSignalUnsafe("search-CTYPE-" + ServiceName + "-error_subsource_request_" + subsource, 1);
}

void TSaasProxyUnistatFrame::OnSubSourceOk(const TString& subsource, ui64 elapsedTimeMicroseconds, ui64 responseSize) {
    const double elapsedTime = ToMilliseconds(elapsedTimeMicroseconds);
    TUnistat::Instance().PushSignalUnsafe("search-CTYPE-" + ServiceName + "-ok_subsource_" + subsource, 1);
    TUnistat::Instance().PushSignalUnsafe("times-CTYPE-" + ServiceName + "-" + subsource + "_subsource", elapsedTime);
    TUnistat::Instance().PushSignalUnsafe(
        "search-CTYPE-" + ServiceName + "-ok_subsource-response_size_KB-" + subsource,
        ToKilobytes(responseSize));

    // from upper search
    if (bool *success = UsedSubsources_.FindPtr(subsource)) {
        *success = true;
    }
}

void TSaasProxyUnistatFrame::OnSubSourceRequest(const TString& subsource, ui32 urlSize, ui64 bodySize) {
    TUnistat::Instance().PushSignalUnsafe("search-CTYPE-" + ServiceName + "-all_subsource_request_" + subsource, 1);
    TUnistat::Instance().PushSignalUnsafe(
        "search-CTYPE-" + ServiceName + "-all_subsource_request-url_size_KB-" + subsource,
        ToKilobytes(urlSize));
    if (bodySize) {
        TUnistat::Instance().PushSignalUnsafe(
            "search-CTYPE-" + ServiceName + "-all_subsource_request-body_size_KB-" + subsource,
            ToKilobytes(urlSize));
    }

    // from upper search
    if (!UsedSubsources_.insert(std::pair<TString, bool>(subsource, false)).second) {
        TUnistat::Instance().PushSignalUnsafe("search-CTYPE-" + ServiceName + "-rerequests_subsource_" + subsource, 1);
    }
}

void TSaasProxyUnistatFrame::DoFinalize() {
    // from upper search
    for (const auto& it: UsedSubsources_) {
        if (!it.second) {
            TUnistat::Instance().PushSignalUnsafe("search-CTYPE-" + ServiceName + "-unanswers_subsource_" + it.first, 1);
        }
    }
}
