#include "files_list_builder.h"

namespace NRTYDeployInfo {

    TFilesBuilderCallback::TFilesBuilderCallback(NRTYDeploy::TNodesStructure& nodes, const NRTYDeploy::ICommonData& common, const NRTYDeploy::TFileContentGenerator::TContext& context, const TString& serviceType, bool forcedOnly, const TString& regFilter)
        : Nodes(nodes)
        , Common(common)
        , Context(context)
        , ServiceType(serviceType)
        , Component(NRTYDeployInfo::IDeployComponentInfo::TFactory::Construct(serviceType))
        , ForcedOnly(forcedOnly)
    {
        try {
            RegExFilter.Compile(regFilter);
        } catch (...) {
            FAIL_LOG("%s", CurrentExceptionMessage().data());
        }
        Component->SetInfo(&Common, Context.SlotInfo.CType);
    }

    bool TFilesBuilderCallback::OnService(const NSearchMapParser::TSearchMapService& info) {
        if (ForcedOnly && !Context.ForceServices.contains(info.Name))
            return false;
        NRTYDeployInfo::IDeployServiceInfo::TPtr builder = Component->BuildServiceInfo(info.Name);
        NRTYDeploy::TFileContentGenerator::TContext compContext = Context;
        compContext.SlotInfo.ServiceType = ServiceType;
        compContext.SlotInfo.Service = info.Name;
        TStringStream errors;
        NRTYDeploy::TNodesStructure structure;
        if (builder->BuildFilesInfo(compContext, errors, "CURRENT")) {
            structure = builder->GetNodes();
        }
        if (Context.ForceServices.contains(info.Name)) {
            NRTYDeployInfo::IDeployServiceInfo::TPtr builderNew = Component->BuildServiceInfo(info.Name);
            builderNew->BuildFilesInfo(compContext, errors, "NEW");

            for (auto& node : builderNew->GetNodes()) {
                TString name = node->GetRename(Context);
                if (RegExFilter.Match(name.data()))
                    structure.UpdateByRename(node, Context);
            }
            Context.ForceStructures[builder->GetCurrentConfigsPath()] = structure;
        }
        for (auto& node : structure) {
            TString name = node->GetRename(Context);
            if (RegExFilter.Match(name.data()))
                Nodes.push_back(node);
        }
        return false;
    }
}
