#pragma once

SgStatement* createStatFromExprs(const std::vector<Expression*>& exprs);

void insertLoopTempalteDeclaration(SgFile* file, const DataDirective& dataDir,
                                   const std::vector<std::string>& distrRules, const std::vector<std::vector<dist>>& distrRulesSt,
                                   const DIST::Arrays<int>& allArrays,
                                   const bool extractDir, const uint64_t regionId);

void insertTempalteDeclarationToMainFile(SgFile* file, const DataDirective& dataDir,
    const std::map<std::string, std::string>& templateDeclInIncludes,
    const std::vector<std::string>& distrRules, const std::vector<std::vector<dist>>& distrRulesSt,
    const DIST::Arrays<int>& allArrays,
    const bool extractDir, const uint64_t regionId,
    const std::set<std::string>& includedToThisFile);

void insertDirectiveToFile(SgFile* file, const char* fin_name, const std::vector<Directive*>& toInsert, const bool extractDir, std::vector<Messages>& messagesForFile);

void insertDistributionToFile(SgFile* file, const char* fin_name, const DataDirective& dataDir,
    const std::set<std::string>& distrArrays, const std::vector<std::string>& distrRules,
    const std::vector<std::vector<dist>>& distrRulesSt,
    const std::vector<std::string>& alignRules,
    const std::map<std::string, std::vector<LoopGraph*>>& loopGraph,
    const DIST::Arrays<int>& allArrays,
    DIST::GraphCSR<int, double, attrType>& reducedG,
    std::map<std::string, std::map<int, std::set<std::string>>>& commentsToInclude,
    std::map<std::string, std::string>& templateDeclInIncludes,
    const bool extractDir, std::vector<Messages>& messagesForFile,
    const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
    const std::map<std::string, FuncInfo*>& funcsInFile,
    const uint64_t regionId,
    const std::set<std::string>& allFileNames);

void insertShadowSpecToFile(SgFile* file, const char* fin_name, const std::set<std::string>& distrArrays,
    DIST::GraphCSR<int, double, attrType>& reducedG,
    std::map<std::string, std::map<int, std::set<std::string>>>& commentsToInclude,
    const bool extractDir, std::vector<Messages>& messagesForFile,
    const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);

void insertDistributionToFile(const char* origFile, const char* outFile, const std::map<int, std::set<std::string>>& commentsToInclude);
void removeDvmSpfDirectives(SgFile* file, bool removeDvm, bool removeSpf, bool toComment);

void insertDistributeDirsToParallelRegions(const std::vector<ParallelRegionLines>* currLines,
    const std::vector<Statement*>& reDistrRulesBefore,
    const std::vector<Statement*>& reDistrRulesAfter,
    const std::vector<Statement*>& reAlignRules);

void insertTemplateModuleUse(SgFile* file, const std::set<uint64_t>& regNum, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
void removeStatementsFromAllproject(const std::set<int>& variants);
void correctTemplateModuleDeclaration(const std::string& folderName);

void insertParallelDirs(SgFile* file, bool extract,
                        std::vector<Directive*>& createdDirectives,
                        std::vector<Messages>& messages,
                        std::map<std::string, std::string>& templateDeclInIncludes,
                        std::map<std::string, std::map<int, std::set<std::string>>>& commentsToInclude,
                        const std::vector<FuncInfo*>& callGraph,
                        const std::vector<ParallelRegion*>& parallelRegions,
                        const std::map<std::string, std::vector<LoopGraph*>>& loopGraph,
                        const std::set<std::string>& allFileNames,
                        const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
                        const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
                        const std::map<DIST::Array*, std::tuple<int, std::string, std::string>>& tableOfUniqNamesByArray);