#include "request.h"
#include "server.h"

#include <saas/library/report_builder/simple.h>
#include <saas/library/searchserver/exception.h>

#include <saas/rtyserver/config/searcher_config.h>
#include <saas/rtyserver/unistat_signals/signals.h>
#include <saas/rtyserver/logging/rty_access.h>
#include <saas/rtyserver/search/source/search_replier.h>

TMetaSearchNehRequest::TMetaSearchNehRequest(YandexHttpServer* server, TMetaSearchServerFeatures& features, const NNeh::IRequestRef& req)
    : TYsNehClientRequest(server, req)
    , Features(features)
    , RequestCreatedTime(Now())
{
    TRTYAccessLog::LogIncoming(GetRequestId(), IReplyContext::GetGlobalActiveObjects(), TString{RequestData().RemoteAddr()}, TString{RequestData().Query()});
    TYsNehClientRequest::ScanQuery();
}

void TMetaSearchNehRequest::Process(void* /*ts*/) {
    IReplyContext::TPtr this_(this);
    try {
        ISearchReplier::TPtr replier;
        if (BuildCommonSearch(RequestData())) {
            replier = CommonSearch->GetSearchReplier(GetRequestData().CgiParam.Get("meta_search"), GetFeatures().GetDefaultKps(), this_);
            if (!replier) {
                ythrow yexception() << "Can't build replier for request: " << GetRequestData().CgiParam.Print();
            }
        } else {
            Y_ENSURE(Features.GetConfig().AllowEmptyNehReplier, "cannot determine request type");
            replier = new TEmptySearchReplier(this_, nullptr, Features.GetConfig());
        }
        replier.Release()->Reply();

    } catch (...) {
        TSaasRTYServerSignals::DoUnistatErrorSearch();
        const TString& message = CurrentExceptionMessage();

        if (this_) {
            TRTYAccessLog::LogError(this_->GetRequestId(), Now() - this_->GetRequestStartTime(), message);
            MakeErrorPage(this_, HTTP_INTERNAL_SERVER_ERROR, message);
        } else {
            TRTYAccessLog::LogError(message);
        }
    }
}

bool TMetaSearchNehRequest::CreateSearcher(const char* /*name*/) {
    Y_ASSERT(!Searcher);
    if (Searcher) {
        return true;
    }

    Searcher = const_cast<TCommonSearch*>(CommonSearch->GetMetaSearch());
    if (Searcher) {
        Searcher->IncreaseSearch();
    }

    return Searcher != nullptr;
}
