#include "controller.h"
#include "verifier.h"

#include <search/report/manager/factory.h>
#include <search/session/manager.h>
#include <saas/rtyserver/common/metrics.h>

//TController
TRTYController::TRTYController(
    TServerConfigConstructorParams& params,
    const TController::IServerDescriptor& sd,
    bool setReportFactory
)
    : TController(params, sd)
{
    if (setReportFactory) {
        static const THolder<NSearchReport::IFactory> reportFactory = NSearchReport::DefaultFactory();
        SetReportFactory(reportFactory.Get());
    }
}

void TRTYController::SaveConfig() {
    TGuardConfig conf(GetConfig());
    const TString strConf(Descriptor.GetConfigString(*this));
    TFixedBufferFileOutput(ConfigParams.Path).Write(strConf);
    ConfigParams.Text = strConf;
}

void TRTYController::CheckConfig(IServerConfig& config, bool onStart) const {
    TRTYServerConfig& rtyCfg = config.GetMeAs<TRTYServerConfig>();
    TMaybe<TString> errorMaybe = DoVerify(rtyCfg, onStart);
    if (Y_UNLIKELY(errorMaybe.Defined())) {
        AbortFromCorruptedConfig("Errors in config: " + errorMaybe.GetRef());
    }
}

bool TRTYController::Process(IMessage* message_) {
    if (TController::Process(message_)) {
        return true;
    }

    if (auto message = message_->As<TMessageGetServerHealth>()) {
        message->Active = GetStatus() == NController::ssbcActive;
        message->NonRunnable = GetStatus() == NController::ssbcNotRunnable;
        if (message->NonRunnable)
            message->NonRunnableDetails = NController::TSlotStatus_Name(GetServerDataStatus());

        message->SlotTimestamp = (ConfigParams.Daemon->GetController().DMOptions.Enabled ? ServerStart : ControllerStart).Seconds();
        message->MustBeAlive = MustByAlive;
        return true;
    }

    return false;
}

TRTYController::TRTYClient::TRTYClient(TController& owner)
    : TController::TClient(owner)
{}

void TRTYController::TRTYClient::ProcessServerStatus() {
    bool brief = RD.CgiParam.Has("brief");
    TGuardConfig g = Owner.GetConfig();

    if (!g) {
        return GetServerStatus(Output(), nullptr, brief);
    }
    GetServerStatus(Output(), g->SafeGetMeAs<TRTYServerConfig>(), brief);
}

void TRTYController::TRTYClient::ProcessSuperMind(IOutputStream& out) const {
    // from YSHttpClientRequest::ProcesssSuperMind()
    TStringStream os;
    TStringStream hs;

    bool isLocal = true;
    try {
        isLocal = IsLocal();
    } catch (...) {
        WARNING_LOG << "An unexpected exception occurred: " << CurrentExceptionMessage() << Endl;
    }

    TStringBuf buf = Buf.Length() ? TStringBuf((const char*)Buf.Data(), Buf.Length()) : RD.Query();

    Owner.GetServer()->GetLogicServer().GetMeAs<TRTYServer>().BaseSearchServer->SuperMind(buf, os, hs, isLocal);

    // Resume copying from YSHttpClientRequest::ProcessSuperMind()
    out << "HTTP/1.1 200 Ok\r\n";
    out << "Content-Type: text/html; charset=utf-8\r\n"
        << "Cache-control: no-cache, max-age=0\r\n"
        << "Expires: Thu, 01 Jan 1970 00:00:01 GMT\r\n";
    out << hs.Str() << "\r\n" << os.Str();
}
