#include "module.h"
#include "globals.h"

#include <util/system/hostname.h>

//
// TRtyOpsConfig
//

void TRtyOpsConfig::DoInit(const TYandexConfig::Section& componentSection) {
    const TYandexConfig::Directives& directives = componentSection.GetDirectives();
    directives.GetValue("Mode", Mode);
    directives.GetValue("Queries", Queries);
    directives.GetValue("LocalHostName", LocalHostName);
    directives.GetValue("BasePort", BasePort);
    directives.GetValue("VirtualArgs", VirtualArgs);

    if (LocalHostName.empty()) {
        LocalHostName = HostName();
    }
}

void TRtyOpsConfig::DoToString(IOutputStream& so) const {
    so << "Mode : " << Mode << Endl;
    so << "Queries : " << Queries << Endl;
    so << "LocalHostName : " << LocalHostName << Endl;
    so << "BasePort : " << BasePort << Endl;
    so << "VirtualArgs : " << VirtualArgs << Endl;
}

bool TRtyOpsConfig::DoCheck() const {
    if (Mode.empty()) {
        return true;
    }

    if (Queries) {
        TFsPath(Queries).CheckExists();
    }

    Y_ENSURE(TRtyOpsModule::IsSupportedMode(Mode));
    Y_ENSURE(0 < BasePort && BasePort < Max<ui16>() / 2);
    return true;
}

//
// TRtyOpsModule
//
TRtyOpsModule::TRtyOpsModule(const IServerConfig& serverConfig)
    : ModuleConfig(*serverConfig.GetModuleConfig<TRtyOpsConfig>(NameStatic()))
{
    DefaultOpContext.Host = ModuleConfig.LocalHostName;
    DefaultOpContext.Port = ModuleConfig.BasePort;

    Op = IRtyOp::TFactory::Construct(ModuleConfig.Mode);
    Op->Init(*this);

    //next calls are doing nothing, but they fix linkage
    NRTYOpsApp::RegisterModulePerf();
    NRTYOpsApp::RegisterModulePool();
}

void TRtyOpsModule::InitContext(TRtyOpContext& ctx) const {
    //TODO: drop TRtyOpContext class and use the main config lol??
    ctx = DefaultOpContext;
}

bool TRtyOpsModule::Start(const TStartContext& /*context*/) {
    if (!Op) {
        return true;
    }

    NOTICE_LOG << "Starting to prepare RTYOPS: " << ModuleConfig.Mode << Endl;
    Op->Prepare();

    NOTICE_LOG << Endl
               << "================================================================" << Endl
               << "--- Starting RTYOPS: " << ModuleConfig.Mode << Endl
               << "================================================================" << Endl
               << Endl << Endl;

    Op->Run(*this);

    NOTICE_LOG << Endl
               << "================================================================" << Endl;
    return true;
}

bool TRtyOpsModule::Stop(const TStopContext& /*context*/) {
    return true;
}

bool TRtyOpsModule::IsSupportedMode(const TString& mode) {
    return IRtyOp::TFactory::Has(mode);
}
